NASM:将多字符输入转换为十进制

时间:2018-12-15 17:03:13

标签: loops assembly x86 nasm

我正在尝试编写一个程序,该程序获得一个具有一位或两位数的数字,并写入Hello!次数与该数字相同。

我用这些帖子来编写我的代码:
NASM: The loop turns into an infinite loop
Check null character in assembly language
Multi-Digit Input from NASM我不明白:)

但是我的代码仅适用于两位数字,而一位数字的结果是错误的。

我的代码:

section .data
    msg db 'Hello!',0xA
    len equ $-msg

section .bss
    n resb 2

section .text
    global _start

_start:
    ;get n
    mov edx, 2
    mov ecx, n
    mov ebx, 0
    mov eax, 3
    int 0x80

    lea     esi,[n]     ;address of our text
    call    toint

    ;loop for print 'Hello!\n'
    print_loop:
        push ecx
        mov edx, len
        mov ecx, msg
        mov ebx, 1
        mov eax, 4
        int 0x80    
        pop ecx
    loop print_loop

mov eax, 1
int 0x80


toint:
    push    eax
    push    ebx
    xor     ebx, ebx
    next_digit:
        movzx   eax, byte[esi]      
        sub     al , '0'
        imul    ebx, 10
        add     ebx, eax
        inc     esi
        cmp     byte [esi] , 0x0    ;check next character is null or not
        jne     next_digit
    ; end_loop:
    mov     ecx, ebx
    pop     eax
    pop     ebx
ret

1 个答案:

答案 0 :(得分:1)

sys_read 调用在EAX中返回发送到输入缓冲区的字符数。因为您允许输入最大2个字符,此计数将为0、1或2。您可以在 toint 例程中使用此信息。

; IN (eax,esi) OUT (ecx)
toint:
    mov     ecx, eax         ; Number of digits
    jecxz   done
    push    eax              ; (1)
    push    ebx              ; (2)
    push    esi              ; (3)
    xor     ebx, ebx
next:
    movzx   eax, byte [esi]      
    sub     al , '0'
    imul    ebx, 10
    add     ebx, eax
    inc     esi
    dec     ecx
    jnz     next
    mov     ecx, ebx
    pop     esi              ; (3)
    pop     ebx              ; (2)
    pop     eax              ; (1)
done:
    ret

请注意,在堆栈中保存/恢复寄存器时要遵循相反的顺序! (您的代码错过了这个...)


4个提示

a。首选MOV变体来加载地址。总是简短的指令。
b。防止输入零。
C。不要使用LOOP。这是很慢的指示。
d。提供退出代码以终止程序。

    mov     esi, n      ; (a)
    call    toint       ; -> ECX
    jecxz   Exit        ; (b)
print_loop:
    ...
    dec     ecx         ; (c)
    jnz     print_loop
Exit:
    xor     ebx, ebx    ; (d)
    mov     eax, 1
    int     0x80