Search code examples
assemblynasmx86-64mach-o

Accepting user input in assembly? Simple program (On macOS)


I'm having some trouble with this simple program that accepts a name from the user and prints "Hello, name here"

This is my code so far...

%define SYSCALL_WRITE 0x2000004
%define SYSCALL_EXIT  0x2000001
%define SYSCALL_READ  0x2000003

SECTION .data
  prompt db "Enter name "
  text2 db "Hello, "

SECTION .bss
  name resb 16

SECTION .text
  global _start

_start:
  call _printText1
  call _getInput
  call _printText2
  call _printName
  mov rax, SYSCALL_EXIT
  mov rdi, 0
  syscall

_printText1:
  mov rax, SYSCALL_WRITE
  mov rdi, 1
  mov rsi, prompt
  mov rdx, 11
  syscall
  ret

_getInput:
  mov rax, SYSCALL_READ
  mov rdi, 0
  mov rsi, name
  mov rdx, 1
  syscall
  ret

_printText2:
  mov rax, SYSCALL_WRITE
  mov rdi, 1
  mov rsi, text2
  mov rdx, 7  
  syscall
  ret

_printName:
  mov rax, SYSCALL_WRITE
  mov rdi, 1
  mov rsi, name
  mov rdx, 16
  syscall
  ret

When I execute it, the output doesn't print "Hello, ". The first letter of the name entered is printed before the next commandline...

nMy-MacBook:Assembly username$ ame

and the rest of the name is accepted as a command argument, for which the system replies

-bash: ame: command not found

What exactly am I doing wrong? I deleted the _getInput and _printName functions and it still only prints "Enter name " without printing "Hello, ".

Thank you.


Solution

  • In Assembly you have to account for every bit; especially when doing input and output.

    Below is your partial code with edits for RDX wherein I chose some arbitrary length.

    The last line shows the command line program execution, prompt, user input, then final output.

    ; reference:
    ; https://stackoverflow.com/questions/47889972/accepting-user-input-in-assembly-simple-program-on-macos
    
    ; lsb_release -a
    ; Distributor ID: Ubuntu
    ; Description:    Ubuntu 16.04.3 LTS
    ; Release:        16.04
    ; Codename:       xenial
    
    ; assemble and link
    ; nasm -f elf64 -g -F dwarf srsrso_001.s -o srsrso_001.o  && ld srsrso_001.o -o srsrso_001
    
    ;%define SYSCALL_WRITE 0x2000004
    ;%define SYSCALL_EXIT  0x2000001
    ;%define SYSCALL_READ  0x2000003
    
    SECTION .data
      prompt db "Enter name "
      text2 db "Hello, ",0xa,0
    
            SYSCALL_WRITE equ       1
            SYSCALL_EXIT  equ       60
            SYSCALL_READ  equ       0
    
    SECTION .bss
      name resb 0xff                ; some length
    
    SECTION .text
      global _start
    
    _start:
     call _printText1
     call _getInput
     call _printText2
     call _printName
    
      mov rax, 60
      mov rdi, 0
      syscall
    
    _printText1:
      mov rax, SYSCALL_WRITE
      mov rdi, 1
      mov rsi, prompt
      mov rdx, 11
      syscall
      ret
    
    _getInput:
      mov rax, SYSCALL_READ
      mov rdi, 0
      mov rsi, name
      mov rdx, 0xff ; some length
      syscall
      ret
    
    _printText2:
      mov rax, SYSCALL_WRITE
      mov rdi, 1
      mov rsi, text2
      mov rdx, 7
      syscall
      ret
    
    _printName:
      mov rax, SYSCALL_WRITE
      mov rdi, 1
      mov rsi, name
      mov rdx, 0xff ; some length
      syscall
      ret
    

    Example output:

    $ ./srsrso_001
    Enter name David John Lewis Benjamen Kyle Smith-Wenson
    Hello, David John Lewis Benjamen Kyle Smith-Wenson