2016-03-20 55 views
0

我现在正在学习assmebler,我终于设法从终端读取输入并用它来计算。Linux上的NASM:使用sys_read在末尾添加额外的行

我使用sys_read为它,它工作得很好,但是当我使用它时,终端像我在运行程序(一行[email protected]:~/ASM$)后按下Enter键一样进入。这在使用scanf时不会发生。

这里是我的代码:

 
sys_read equ 3 
sys_write equ 4 
stdout equ 1 
stdin  equ 2 

section .data 
    prompt db "Enter two 1-digit numbers for an integer division.", 10, 0 
    result db 10, "%i/%i = %i.", 10, 0 

section .bss 
    a resb 4 
    b resb 4 
    c resb 4 

section .text 
    extern printf 
    global main 

main: 
    push ebp 
    mov ebp, esp 
    push ebx 
    push esi 
    push edi 

    push prompt 
    call printf 

    mov eax, sys_read 
    mov ebx, stdin 
    mov ecx, a 
    mov edx, 1 
    int 80h 

    sub dword [a], 0x30 

    mov eax, sys_read 
    mov ebx, stdin 
    mov ecx, b 
    mov edx, 1 
    int 80h 

    mov eax, sys_read 
    mov ebx, stdin 
    mov ecx, b 
    mov edx, 1 
    int 80h 

    sub dword [b], 0x30 

    mov dx, 0 
    mov ax, [a] 
    div dword [b] 
    mov [c], ax 
    push dword [c] 
    push dword [b] 
    push dword [a] 
    push result 
    call printf 

    add esp, 40 

    pop edi 
    pop esi 
    pop ebx 
    mov esp, ebp 
    pop ebp 
    ret 

这里是输出我得到:

 
[email protected]:~/ASM$ ./div 
Enter two 1-digit numbers for an integer division. 
1 1 

1/1 = 1. 
[email protected]:~/ASM$ 
[email protected]:~/ASM$ 

我不明白为什么这个额外的线出现。

+2

发生什么事情是,默认情况下,Linux控制台通常设置为行缓冲模式。字符在处理之前保留在缓冲区中。你做3个读1字节的每一个消耗'1 1',但是将实际的新行留在缓冲区中。在你的程序中你不会对它做任何事情,所以它会在shell中被处理。你可以在读完3个字符后刷新stdin,或者将最后一个'sys_read'改为读取2个字符而不是1.这将消耗换行符。 –

+0

谢谢,修好了! – cmdj13

+1

没问题。另一个观察结果是stdin是文件描述符0,stdout是文件描述符1.您似乎使用了错误的值。 –

回答

0

你的结果数据包含字符串之前一个额外的换行字符(10)要打印:

result db 10, "%i/%i = %i.", 10, 0 
      ^^ 

卸下这将移除多余的换行符在输出中。

您可以通过从标准输入消耗更多字符(通过刷新缓冲区或从缓冲区中读取三个以上字符)来删除额外的外壳行。您输入数据的换行符也会存储在行的缓冲区中,如果未通过代码读取,则shell将以空行形式读取。 (也就是说,如果你只是在没有输入任何东西的情况下按下输入框,它将显示与shell相同的行为。)

另外,我建议使用扩展的32位寄存器来替代16位寄存器,因为你的变量是32位的。

+0

唯一改变的是我在输入行和打印结果行之间没有换行符。 我知道32位会更好,但它是关于获取和计算输入。 – cmdj13

+0

@ cmdj13 - 这不就是你要找的行为吗? (顺便说一句,看我的编辑,因为它看起来你使用的是32位变量而不是16位) – owacoder

+0

不,我不想有额外的 root @ kali:〜/ ASM $ line。 – cmdj13

相关问题