Read and print user input with x86 assembly (GNU/Linux)

前端 未结 2 557
一生所求
一生所求 2021-01-14 17:11

I\'m learning x86 assembly on GNU/Linux, and I\'m trying to write a program that reads user input from stdin and prints it on stdout.

The following code does work, b

相关标签:
2条回答
  • 2021-01-14 17:22

    str: db 100 is wrong. You allocated one byte with the value 100. Correct is: str: times 100 db 0 to allocate 100 bytes with the value 0.

    You've got two problems:

    1) To get the number of inputted bytes you can evaluate the return value of the read-function (int 80h / fn 3) in EAX.

    2) If you input more characters than "allowed" the rest is stored in the input buffer which you have to empty. A possible method to do this is in the following example:

    global _start
    
    section .data
        str: times 100 db 0 ; Allocate buffer of 100 bytes
        lf:  db 10          ; LF for full str-buffer
    
    section .bss
        e1_len resd 1
        dummy resd 1
    
    section .text
    
    _start:
        mov eax, 3          ; Read user input into str
        mov ebx, 0          ; |
        mov ecx, str        ; | <- destination
        mov edx, 100        ; | <- length
        int 80h             ; \
    
        mov [e1_len],eax    ; Store number of inputted bytes
        cmp eax, edx        ; all bytes read?
        jb .2               ; yes: ok
        mov bl,[ecx+eax-1]  ; BL = last byte in buffer
        cmp bl,10           ; LF in buffer?
        je .2               ; yes: ok
        inc DWORD [e1_len]  ; no: length++ (include 'lf')
    
        .1:                 ; Loop
        mov eax,3           ; SYS_READ
        mov ebx, 0          ; EBX=0: STDIN
        mov ecx, dummy      ; pointer to a temporary buffer
        mov edx, 1          ; read one byte
        int 0x80            ; syscall
        test eax, eax       ; EOF?
        jz .2               ; yes: ok
        mov al,[dummy]      ; AL = character
        cmp al, 10          ; character = LF ?
        jne .1              ; no -> next character
        .2:                 ; end of loop
    
        mov eax, 4          ; Print 100 bytes starting from str
        mov ebx, 1          ; |
        mov ecx, str        ; | <- source
        mov edx, [e1_len]   ; | <- length
        int 80h             ; \
    
        mov eax, 1          ; Return
        mov ebx, 0          ; | <- return code
        int 80h             ; \
    
    0 讨论(0)
  • 2021-01-14 17:36

    Here's one way of calculating the length of a string in x86 assembly:

    lea esi,[string]
    mov ecx,-1    ; Start with ecx = -1
    xor eax,eax   ; Clear eax
    cld           ; Make scasb scan forward 
    repne scasb   ; while (ecx != 0) { ecx--; if (*esi++ == al) break; }
    ; ecx now contains -1 - (strlen(string) + 1) == -strlen(string) - 2
    not ecx       ; Inverting ecx gives us -(-strlen(string) - 2) - 1 == strlen(string) + 1 
    dec ecx       ; Subtract 1 to get strlen(string)
    

    This assumes that the string is NUL-terminated ('\0'). If the string uses some other terminator you'll have to initialize al to that value before repne scasb.

    0 讨论(0)
提交回复
热议问题