Assembly x86 NASM - Avoid read return key

2019-02-24 06:16发布

问题:

I just started learning assembly and i'm not finding any useful content that helps.

I'm creating a simple program that reads user input,basically:

section .bss
    opA: resw 1
    opB: resw 1

section .text
    global _start

    inputA:
    mov EAX, 3
    mov EBX, 0
    mov ECX, opA
    mov EDX, 1
    int 80h

    inputB:
    mov EAX, 3
    mov EBX, 0
    mov ECX, opB
    mov EDX, 1
    int 80h

    /*terminate*/

The problem is that after i enter the first value and hit return,the second sys_read is skipped(i believe it is reading the '\n' character).

So i tried comparing if opB stored '\n' and in positive case i jump back to 'inputB:',like this:

cpm word[opA], '\n'
je inputB

But it is not working!How cal i solve this?

Simpler, How to remove a line break from a variable?

回答1:

One option is to flush the stdin buffer:

section .data
    opA: db 0
    opB: db 0
    LF: db 10

section .text
global _start
_start:

    inputA:
    mov EAX, 3
    mov EBX, 0
    mov ECX, opA
    mov EDX, 1
    int 80h

    mov eax,54          ; kernel function SYS_IOCTL
    mov ebx,0           ; EBX=0: STDIN
    mov ecx,0x540B      ; ECX=0x540B: TCFLSH
    xor edx, edx        ; EDX=0: TCIFLUSH
    int 0x80            ; sys_call

    inputB:
    mov EAX, 3
    mov EBX, 0
    mov ECX, opB
    mov EDX, 1
    int 80h

    mov eax,54          ; kernel function SYS_IOCTL
    mov ebx,0           ; EBX=0: STDIN
    mov ecx,0x540B      ; ECX=0x540B: TCFLSH
    xor edx, edx        ; EDX=0: TCIFLUSH
    int 0x80            ; sys_call

    print:
    mov edx,3
    mov ecx,opA
    mov ebx,1
    mov eax,4
    int 0x80

    exit:
    mov eax, 1
    mov ebx, 0
    int 0x80

Another option - which works with pipes - is to read stdin until EOF or LF:

section .data
    opA: db 0
    opB: db 0
    LF: db 10
    dummy: db 0

section .text
global _start

reads:
    .1:                 ; Loop
    mov eax,3           ; kernel function SYS_READ
    mov ebx, 0          ; EBX=0: STDIN
    mov ecx, dummy      ; dummy buffer
    mov edx, 1          ; number of bytes to read
    int 0x80            ; sys_call
    test eax, eax       ; EOF?
    jz .2               ; yes: ok
    mov al,[dummy]      ; no: fetched character
    cmp al, 10          ; character == LF ?
    jne .1              ; no -> loop (i.e. fetch next character)
    .2
    ret

_start:

    inputA:
    mov EAX, 3
    mov EBX, 0
    mov ECX, opA
    mov EDX, 1
    int 80h

    call reads

    inputB:
    mov EAX, 3
    mov EBX, 0
    mov ECX, opB
    mov EDX, 1
    int 80h

    call reads

    print:
    mov edx,3
    mov ecx,opA
    mov ebx,1
    mov eax,4
    int 0x80

    exit:
    mov eax, 1
    mov ebx, 0
    int 0x80