Created
July 18, 2019 20:11
-
-
Save NateSeymour/8387b4622feb9f9e4ba12f549ea046e3 to your computer and use it in GitHub Desktop.
hello.s - read "infinitely" long user input from stdin and display it
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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