NASM - 添加两个数字(一个来自标准输入,另一个硬编码)

NASM - adding two numbers (one from stdin, another hardcoded)

我是 NASM 的新手。我想添加两个数字,一个来自 stdin,第二个是硬编码的,然后在屏幕上打印结果。但是我得到的结果是问号(�)。这是代码:

section .bss
    buf:   resb    1
    res:   resb    1
section .text
    global  _start

_read:
    mov     eax,    3       ; sys_read
    mov     ebx,    0       ; stdin
    mov     ecx,    buf    ; buffer
    mov     edx,    1       ; read byte count
    int     80h

_adding:   
    add ecx, 10
    sub ecx, '0'
    mov [res], ecx 

_write:    
    mov     eax,    4       ; sys_write
    mov     ebx,    1       ; stdout
    mov     ecx,    res    ; buffer
    mov     edx,    1       ; write byte count
    int     80h

_exit:
    mov     eax,    1       ; exit
    mov     ebx,    0       ; exit status
    int     80h

我试过样例展示,添加如下:

_adding:
    sub ecx, '0'
    mov eax, '1'            ; put 1
    sub eax, '0'
    add eax, ecx             ; adding 1+'user input'
    add eax, '0'
    mov [res], eax

但是我没有得到任何输出。 如有任何帮助,谢谢。

您似乎正在从终端读取 ASCII(1 个字符),然后将 10 添加到该字符并减去“0”(0x30)。你输入的是什么字符?如果输入数字('0'到'9'即0x30到0x39),结果将是0x0A到0x13的ASCII码,这些是不可打印的控制字符。

尝试将 add acx,10 更改为 add acx,1 并删除包含 sub ecx,'0' 的行。如果您输入“0”,您应该得到“1”。

如果这不起作用,那么您的 IO 中还有其他错误。我对 int 80h 了解不够,无法提供帮助。

您甚至忘记使用您阅读的值。当然在 [buf] 中。此外,它是 byte 而不是 dword (尽管后者在这种情况下意外地起作用)。此外,您尝试的简单方法仅适用于个位数,因此加 10 已经注定。此外,您通过减去 '0' 来调整输入,但不要将其加回输出(就像在底部的示例中所做的那样)。

这是您的代码的一个工作示例。它仅在结果 <10 时有效,也就是当您的结果只有 1 位时。

section .bss
    buf:   resb    1
    res:   resb    1
section .text
    global  _start
_start:             ; you made the label _start global, 
                    ; but you forgot to add the label.
_read:
    mov     eax, 3      ; sys_read
    mov     ebx, 0      ; stdin
    mov     ecx, buf    ; buffer (memory address, where read should save 1 byte)
    mov     edx, 1      ; read byte count
    int     80h

_adding:   
    mov     cl, [buf]   ; copy 1 byte (the ASCII-char) from address buf into cl
    sub     cl, '0'     ; same as "sub cl, 30h"; changes ASCII number into binary number. (This is optional)
    add     cl, 1       ; it will not work, when the result is >9! 
                        ; Because then you get 2 digits
    add     cl, '0'     ; convert binary number back to ascii-char. 
                        ; (This is optional)
    mov     [res], cl   ; you could use buf instead of res, too.

_write:    
    mov     eax,    4           ; sys_write
    mov     ebx,    1           ; stdout
    mov     ecx,    res         ; buffer
    mov     edx,    1           ; write byte count
    int     80h

_exit:
    mov     eax,    1           ; exit
    mov     ebx,    0           ; exit status
    int     80h