My code below, for some reason only outputs the last 2 digits of the number, regardless of how long the umber is... Can someone please tell me the issue/how to fix? Of course I want to print out the whole number, but it isn't letting me. please help, thank you
global _start
section .text
_start:
mov eax, 6789 ; The number to be printed
mov ebx, 0 ; count the digits
mov ecx, 10 ; divisor
divide:
mov edx, 0
div ecx ; divide the number into eax and edx | for 6789, eax = 678, edx = 9
push ebx ; push current count into the stack
inc ebx ; increase the number of digits
push edx ; push the value of remainder into the stack
cmp eax, 0 ; check if eax = 0, means all digits are pushed into the stack
jne divide
; Stack at the end of divide: (entry from left): 6, 3, 7, 2, 8, 1, 9, 0 ]
print:
pop edx ; take out the value pushed previously in the stack
add edx, 0x30 ; Convert to ASCII
mov [digit], edx ; Save the value of edx to digit
mov eax, 4 ;\
mov ebx, 1 ; |---> use sys_write to print on screen
mov ecx, digit ; |
mov edx, 1 ;/
int 0x80
pop ebx ; Restore value of count to ebx from the stack
cmp ebx, 0 ; compare whether count is equal to 0
jnz print ; if not 0, go back to print and print the next digit on the screen
concl:
mov eax, 1
mov ebx, 0
int 0x80
section .data
digit db 0
I have used gdb-(GEF) for debugging and the stack seems to be functioning properly, same with all the registers.
An example output would be for the number: 6789 The output is: 89
CodePudding user response:
A bad case of line continuation
mov [digit], edx ; Save the value of edx to digit mov eax, 4 ;\ mov ebx, 1 ; |---> use sys_write to print on screen mov ecx, digit ; | mov edx, 1 ;/
Don't inadvertently put a backslash character at the end of a line because the assembler will consider it to be the signal for line continuation, which means that the line that follows gets stitched to the current line, and in your case it produces this:
mov [digit], edx ; Save the value of edx to digit
mov eax, 4 ; mov ebx, 1 ; |---> use sys_write to print on screen
mov ecx, digit ; |
mov edx, 1 ;/
The part that loads EBX with the reference to STDOUT is now behind the semicolon and became a mere comment in the program. You won't find it in the executable file. The print loop will be using whatever happens to be in EBX.
In your test run with the number 6789, the first 2 iterations of the print loop were using EBX=4 and EBX=3, but the last 2 iterations were using EBX=2 and EBX=1. Now STDERR=2 and STDOUT=1, and both write to the screen. That's why you only ever got output for the last 2 digits.
Notwithstanding that you should write mov [digit], dl
instead of mov [digit], edx
, the code seems correct. Your unusual choice to double push
is matched by double pop
, so that is fine. You just need to remove that unlucky \