running DOS Debug script - debugging

the following script works fine if I type it line-by-line in debug. When I copy it to a file called script.txt, it hangs up after "enter 3 numbers". I run it like so:
D:>debug < script.txt
the file is:
a
mov cx, 3
jmp 0119
db 0d,0a,"enter 3 numbers",0d,0a,"$"
mov dx, 0105
mov ah, 09
int 21h
mov ah, 01
int 21h
and al, 0f
add bl, al
mov dl, 0a
mov ah, 02
int 21h
loop 0120
jmp 013a
db 0d,0a,"sum: ","$"
mov dx,0132
mov ah, 09
int 21h
or bl, 30
mov dl, bl
mov ah, 02
int 21h
mov ax, 4c00
int 21h
g
what am I doing wrong? Any hints or links appreciated.
keith

You redirected input to debug to be from the script, not from the console, so debug is never receiving your keystrokes The program is hanging, waiting for more data to come in from the script.
If you put 3 numbers after the 'g' in the script, it should continue

You're telling debug to take all its input from script.txt, so when your program tries to read the numbers from standard input, it's reading from the file, not from the console.

good explanations.
Thanks Michael, your suggestion worked, but I want to get input from the console and still run a script so I don't have to type the entire code to run it again.
Thanks jdigital!, that's the answer I'm looking for. Using your hints (in comments above) I was able to make a simple working script:
a
mov cx, 3
jmp 0119
db 0d,0a,"enter 3 numbers",0d,0a,"$"
mov dx, 0105
mov ah, 09
int 21h
mov ah, 0 ; for console input
int 16h ; use int 16h function 0.
mov dl,al ; echo input to screen
mov ah,02
int 21h
and al, 0f
add bl, al
mov dl, 0a
mov ah, 02
int 21h
loop 0120
jmp 0140
db 0d,0a,"sum: ","$"
mov dx,0138
mov ah, 09
int 21h
or bl, 30
mov dl, bl
mov ah, 02
int 21h
mov ax, 4c00
int 21h
g

enter 3 numbers
9
7
9
sum: 9
Seam your program not working ... maybe is need to use stack , not regs.

Related

Getting error after copying 8086 code from book

I am having troubles running this 8086 programs that take one letter input from keyboard and outputs "the letter you typed is _"
I just started reading my college book on this and trying to run some code from the book on my computer but got stuck here.
The code below is from my college book.
I am running it in emu8086 emulator.
CODE SEGMENT
; set the DS register
MOV AX, DATA
MOV DS, AX
; Read Keyboard
MOV AH, 08H
INT 21H
; Save input
MOV BL, AL
; Display first part of Message
MOV AH, 09H
MOV DX, OFFSET MESSAGE
INT 21H
; Display character of BL register
MOV AH, 02H
MOV DL, BL
INT 21H
; Exit to DOS
MOV AX, 4C00H
INT 21H
CODE ENDS
DATA SEGMENT
MESSAGE DB “The letter you typed is $”
DATA ENDS
END
The error I am getting is
INT 21h, AH=09h -
address: 00020
byte 24h not found after 2000 bytes.
; correct example of INT 21h/9h:
mov dx, offset msg
mov ah, 9
int 21h
ret
msg db "Hello$"
After further debugging by myself I have concluded there is some problem with this
MOV AX, DATA
MOV DS, AX
If I remove it from my code it executes but with some garbage in the start.
Any suggestions will be appreciated.
Update:
Image of emulator around the string "the letter you typed $"
umm so after giving up for 2 days I referenced another book, and in there they weren't using segments. So I removed segments and the program ran flawlessly here is the new code:
ORG 100H
MOV AH, 08H ; Read Keyboard
INT 21H
MOV BL, AL ; Save input
MOV AH, 09H ; Display first part of Message
MOV DX, OFFSET MESSAGE
INT 21H
MOV AH, 02H ; Display character of BL register
MOV DL, BL
INT 21H
MOV AX, 4C00H ; Exit to DOS
INT 21H
RET
MESSAGE DB "The letter you typed is $"
Thank you to everyone who tried to help me, really appreciated.

How to print an integer stored in a variable

So I have a program in 8086 assembly that allows the user to enter 2 digits, store them in a variable and then print out the number:
data segment
broj db ?
ends
stack segment
dw 128 dup(0)
ends
code segment
mov ax, data
mov ds, ax
mov es, ax
mov ah, 1h
int 21h
sub al, 48d
mov bl, 10d
mul bl
mov broj, al
mov ah, 1h
int 21h
sub al, 48d
add broj, al
mov dl, broj
sub dl, 48d
mov ah, 2h
int 21h
mov ax, 4c00h
int 21h
ends
However whenever I enter a number for example 21 it doesn't give me the number instead it gives me ASCII Code for that value.
Can anyone help?!
However whenever I enter a number for example 21 it doesn't give me the number instead it gives me ASCII Code for that value.
If you feed (input) your program a number that consists of 2 digits, then you'll have to print also 2 digits! Currently your code contains just the one character output function.
First divide the number in broj by 10 giving a quotient (in AL) and a remainder (in AH).
Convert the quotient to character (Add 48) and print it.
Convert the remainder to character (Add 48) and print it.
Example:
mov al, broj
mov ah, 0
mov bl, 10
div bl
add ax, "00"
mov dx, ax
mov ah, 02h
int 21h
mov dl, dh
mov ah, 02h
int 21h

Why does the following 8086 assembly code only display numbers up to 2559?

What am I trying to do ?
I want to get a 16-bit number from the user and print It on the console.
What Is the problem ?
Well my code works fine If the number entered Is less than 2600 but the moment I enter 2600 It displays "40" and for 2601 "41" and so on. Shouldn't It display numbers up to 65535 ? Because I am storing the value In the bx register which Is 16-bit and which can store at most 65535. Then why only 2559 ?
My code:
.model small
.data
msg db 10,13,'Enter a 16bit number: $'
newline db 10,13,'$'
.code
main:
mov ax, #data
mov ds, ax
mov cl, 10
mov bx, 0
mov ah, 09h
lea dx, msg
int 21h
call get16bitNum
mov ah, 09h
lea dx, newline
int 21h
mov ax, '$'
push ax
mov ax, bx
store:
div cl
cmp al, 0
mov bh, 0
mov bl, ah
push bx
je continue
mov ah, 0
jmp store
continue:
pop ax
cmp ax, '$'
je ext
mov bx, ax
mov ah, 02h
mov dx, bx
add dx, 48
int 21h
jmp continue
ext:
mov ah, 04ch
int 21h
proc get16bitNum
aggregate:
mov ah, 01h
int 21h
cmp al, 13
je return
mov ah, 0
sub al, 48
mov dx, bx
mov bx, ax
mov ax, dx
mul cl
add bx,ax
jmp aggregate
return:
ret
endp
end main
You don't actually retrieve a 16-bit number!
You keep the desired input in BX, and so you need to multiply the whole of BX by 10. You do this using a word sized multiplication.
proc get16bitNum
aggregate:
mov ah, 01h
int 21h
cmp al, 13
je return
mov ah, 0
sub al, 48 ;AX is 0 to 9
xchg ax, bx ;New digit temporarily in BX
mov cx, 10
mul cx ;Product is in DX:AX, but we won't use DX!
add bx ,ax ;Add new digit
jmp aggregate
return:
ret
You don't display the 16-bit number
The procedure to convert the number into text will definitely need to use the word sized division.
For an excellent explanation on how to do this see this recent post Displaying numbers with DOS. It explains in great detail everything you need to know about converting numbers. It even uses the same technique of pushing some value in the stack (You used a $ character for this) to know where the number ends.
ps. If you find the info in the linked post useful don't hesitate to upvote it. (Of course I hope you find my answer useful too!)
8 bit div produces 8 bit quotient and remainder.
When you divide 2600 by 10 you get an 8 bit quotient, losing higher bits.
You should use 16 bit division.

TASM giving no output after compile

I have a program that compiles correctly with zero error or warning but does not display the output I cannot guess the reason for no output
.model small
.data
a dw 1234H
b dw 0100H
.code
Process:
MOV AX, #data
MOV DS, AX
Mov AX, a
MOV BX, b
SUB AX, BX
MOV CH, 04H
MOV CL, 04H
MOV BX, AX
X: ROL BX, CL
MOV DL, BL
AND DL, 0FH
CMP DL, 09
JBE Y
ADD DL, 07
Y: ADD DL, 30H
INT 21H
DEC CH
JNZ X
MOV AH, 4CH
INT 21H
END Process;
If you intend to write characters one at a time to STDOUT then DL should contain the character and AH must be set to 02H before you invoke INT 21H. So,
Y: ADD DL, 30H
MOV AH, 02H
INT 21H
You can also set AH to 02H before the loop starts, saving on the number MOV instructions.

reading from File in assembly

i am trying to read a username and a password from a file in x86 assembly for the perpose of authentication
obviously the file consists of two lines , the user name and the password how can i read the two lines seperately and compare them?
My attempt:
proc read_file
mov ah,3dh
lea dx,file_name
int 21h
mov bx, ax
xor si,si
repeat:
mov ah, 3fh
lea dx, buffer
mov cx, 100
int 21h
mov si, ax
mov buffer[si], '$'
mov ah, 09h
int 21h ;print on screen
cmp si, 100
je repeat
jmp stop;jump to end
stop:
RET
read_file ENDP
Go here and read up on functions like CreateFile and ReadFile.
You should use system class to do that and it depends on whether you use Windows or Linux.
Check this : http://www.freebsd.org/doc/en/books/developers-handbook/x86-system-calls.html

Resources