assembly 转换为ASCII时仅打印最后2位数字?[x86_32]-NASM

92vpleto  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(128)

我下面的代码,由于某种原因,只输出数字的最后2位数字,不管数字有多长......有人能告诉我这个问题/如何解决吗?当然我想打印出整个数字,但它不允许我。请帮助,谢谢

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

我已经使用gdb-(GEF)进行调试,堆栈似乎工作正常,所有寄存器也是如此。
以下数字的输出示例为:6789输出为:89

sr4lhrrt

sr4lhrrt1#

行继续符的大小写错误

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          ;/

不要不小心在行尾放了一个反斜杠字符,因为汇编程序会把它看作是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          ;/

加载EBX并引用STDOUT的部分现在位于分号后面,成为程序中的一个注解。在可执行文件中找不到它。print 循环将使用EBX中的任何内容。
在你的测试运行中,print 循环的前两次迭代使用EBX=4和EBX=3,但是最后两次迭代使用EBX=2和EBX=1。现在STDERR=2和STDOUT=1,并且都写到屏幕上。这就是为什么你只得到最后两位数的输出。
尽管您应该写mov [digit], dl而不是mov [digit], edx,但代码看起来是正确的。您不寻常地选择了将push加倍,结果是将pop加倍,因此这是正确的。您只需要删除那个不幸的****

相关问题