NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: TOMAR on July 28, 2013, 05:34:28 PM
-
I am new to x86 assembly and trying to understand part of code which converts a Binary number to Decimal number .Below is the code
org 100h
push ax
push cx
push dx
push si
mov dx,10b
mov ax,dx ;Assuming number to print starts in DX
mov si,10 ;decimal 10
xor cx,cx ;Initialize count at 0
NonZero:
xor dx,dx ;Clear last remainder
div si
push dx ;Save digits in reverse order
inc cx
or ax,ax ;Is original number down to 0 yet?
jnz NonZero ;No, continue looping
mov ah,02h
WriteDigitLoop:
pop dx
add dx,"0" ;Convert to ASCII
int 21h ; and print
loop WriteDigitLoop
EndDecimal:
pop si
pop dx
pop cx
pop ax
I got into bit of confusion the way code is working,When I use 10b as input to dx ,how its printing 2 ,in case of 10b first 0 is pushed to stack and then 1 is pushed ,while printing 1 is poped out first ,add dx,"0"(decimal 49) will cause 1(ASCII) to be printed on screen and then 0 is poped out which causes 0(ASCII) to be printed out ,how come 2 printed out ,what point of time value to dx become 50 so that 2 is printed .
Could anybody explain me part of code where value of dx become in decimal??
-
This seems like a real good place to use a debugger. You can watch the register contents change with each instruction.
-
hi,
this algo converts machine binary from register AX to ASCII decimal code of that number, so that you could see it on the screen.
this is not an algo, that converts form machine binary to ASCII binary
10(binary) = 2(decimal)
all about is that algo is a rest from dividing. it's stored in DX. for example if you:
143 / 10 = 14 and rest = 3(DX = 3) + "0" you will get ASCII code of that number
14 / 10 = 1 and rest = 4
1 / 10 = 0 and rest = 1
and you got codes of 143.
-
in case of 10b first 0 is pushed to stack and then 1 is pushed
This seems to be where you're going wrong, Tomar. When we divide 10b or 2 decimal by 10 decimal, the quotient is zero (in ax) and the remainer is 2 (in dx). It is this 2 (or 10b if you like) that gets pushed to the stack. Since the quotient is zero, we're all done, and the 2 is the only thing pushed to the stack. Then we pop it and add '0' (or 30h or 48 decimal). this "converts" the number 2 to the ascii code for the character '2' (32h or 50 decimal) which is what we want to print.
If we wanted to print a character '1' followed by a character '0', we could have divided by 2 (10b) instead of 10 decimal (0Ah or 1010b). It's much faster to divide by 2 with a "shr" than with a "div", but "div" works too - try it!
"hexadecimal", "decimal" and "binary" are just different ways to represent a number - it's the same number. "binary" may be confusing, since we might mean "a string of '1's and '0's" or we might mean "a plain number". The computer stores everything as a series of 1 bits and 0 bits, but we do not usually see the individual bits, even in a debugger.
Joe/dogman is correct that stepping through your code in a debugger will help you understand it. Keep in mind that a debugger represents everything as hex. When you do "mov si, 10", you'll see "0A", not "10" - its the same number. When I first tried to use "debug" I didn't know that 'q' would get me back to the command prompt - I had to reboot to get out of "debug". The other important command is '?' - this will print out the other commands you can use. When you get to "int 21h" (the debugger won't show the 'h'), use 'p' (proceed) not 't' (trace). Tracing through the "bowels of DOS" may be interesting, but my experience is that it crashes debug before you learn much. Note that to debug your program, do "debug myprog.com" - the ".com" has to be there! There are other (better?) debuggers besides "debug", but "debug" is usually available. Try it - you won't break anything (probably :) ).
Your code, as posted, doesn't contain any "exit" to get back to dos. This will probably cause a crash.
mov ah, 4Ch
mov al, 0 ; indicate "no error"
int 21h
is the recommended method to get back to dos, although there are other ways.
Best,
Frank
-
Thanks Frank for helping me out again.Your statement "When we divide 10b or 2 decimal by 10 decimal" made picture very clear for me though I am feeling like fool here.
The point of using Debugger,Since I am on DosBox not sure how in DosBox Debugger can be used .Would you like to light upon bit of using Debugger in Dosbox or in General how to debug an assembly Program.
-
No need to feel like a fool - nobody is born knowing this stuff!
As to DosBox... now it's my turn to feel like a fool. I've never been able to install DosBox on my system. I would have guessed that "debug" came with it, but I'm really not sure. What happens if you just type "debug"? If it doesn't work, you'll have to install it. I don't know how. Anyone know?
Best,
Frank
-
you can download debug.com form http://www.japheth.de/debxxf.html (http://www.japheth.de/debxxf.html). Extract it and mount that drive, where you extracted it in DosBox . Copy to that directory program you want to debug. go into that folder and type debug example.exe to load your program to debugger. when it is running type: ?, for help.
on this website you will find also tutorial how to use it.
-
Thanks Null ,will give it a try.