Skip to content

Instantly share code, notes, and snippets.

@NateSeymour
Created July 18, 2019 20:11
Show Gist options
  • Save NateSeymour/8387b4622feb9f9e4ba12f549ea046e3 to your computer and use it in GitHub Desktop.
Save NateSeymour/8387b4622feb9f9e4ba12f549ea046e3 to your computer and use it in GitHub Desktop.
hello.s - read "infinitely" long user input from stdin and display it
# hello.s - read "infinitely" long user input from stdin and display it
# Error codes
# err_open - 0x0
# err_close - 0x1
.data
# Text constants
greeting: .asciz "Hello, what is your name?\n"
hello: .asciz "\nHi there, %s"
error_message: .asciz "There was an error, code: %i\n"
end_message: .asciz "\nProgram exited successfully\n"
path_stdin: .asciz "/dev/stdin"
# Other variables
.lcomm stdin, 4 # Used to store stdin file des.
.lcomm p_rbuf, 4 # Pointer to the read buffer
.lcomm s_rbuf, 4 # Size of the read buffer
.text
.globl _main
open_stdin:
# Open stdin for reading
# int open(const char *path, int oflag);
subl $0x4, %esp
pushl $0x0 # O_RDONLY
pushl $path_stdin
call _open
movl %eax, stdin # Store file descriptor
addl $0xC, %esp
# Error handling
cmpl $0x0, stdin
jg open_no_error
subl $0xC, %esp
movl $0x0, %eax
call error
open_no_error:
ret
close_stdin:
# Close the file
subl $0x8, %esp
pushl stdin
call _close
addl $0xC, %esp
# Error handling
cmpl $0x0, %eax
je close_no_error
subl $0xC, %esp
movl $0x1, %eax
call error
close_no_error:
ret
read_stdin:
# Clear out the pointer and size of buffer
movl $0x0, p_rbuf
movl $0x0, s_rbuf
read_allocation:
addl $0xA, s_rbuf # Increment the buffer size by one chunk (0xA)
cmpl $0xA, s_rbuf # If not the first, reallocate
jnz read_reallocate
# Allocate some memory for the read
subl $0x8, %esp
pushl s_rbuf
call _malloc
jmp reallocate_done
read_reallocate:
subl $0x4, %esp
pushl s_rbuf
pushl p_rbuf
call _realloc
reallocate_done:
addl $0xC, %esp
movl %eax, p_rbuf
# Do the read
# ssize_t read(int fildes, void *buf, size_t nbyte);
movl s_rbuf, %eax
subl $0xA, %eax
movl p_rbuf, %ebx
addl %eax, %ebx
pushl $0xA
pushl %ebx
pushl stdin
call _read
addl $0xC, %esp
# If we read the full chunk, we need to keep reading
# This is what allows us to read the ENTIRE input
# that we get from the user
cmpl $0xA, %eax
je read_allocation
ret
_main:
# Print out the intro
subl $0x8, %esp
pushl $greeting
call _printf
addl $0xC, %esp
# Open the stdin file descriptor
subl $0xC, %esp
call open_stdin
addl $0xC, %esp
# Read from the file descriptor
subl $0xC, %esp
call read_stdin
addl $0xC, %esp
# Print the input
subl $0x4, %esp
pushl p_rbuf
pushl $hello
call _printf
addl $0xC, %esp
# Close the file descriptor
subl $0xC, %esp
call close_stdin
addl $0xC, %esp
# Free the memory
subl $0x8, %esp
pushl p_rbuf
call _free
addl $0xC, %esp
# Print the exit message
subl $0x8, %esp
pushl $end_message
call _printf
call _exit
error:
subl $0x4, %esp
pushl %eax
pushl $error_message
call _printf
call _exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment