Created
October 29, 2017 04:01
-
-
Save dstein64/890e02e8e277f17d931c8a250ceaaf44 to your computer and use it in GitHub Desktop.
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
/*** echo.s ***/ | |
// Description | |
// echo - print arguments to stdout | |
// Synopsis | |
// echo [STRING]... | |
// Build | |
// $ as --32 -o echo.o echo.s | |
// $ ld -m elf_i386 -o echo echo.o | |
.section .text | |
# ************************************ | |
# * print macro | |
# * Caller is responsible for setting | |
# * %ecx and %edx, and saving %eax and | |
# * %ebx if necessary. | |
# ************************************ | |
.macro print | |
movl $4, %eax | |
movl $1, %ebx | |
int $0x80 | |
.endm | |
# ************************************ | |
# * int strlen(char* str); | |
# * Returns the length of a string. | |
# ************************************ | |
.type strlen, @function | |
strlen: | |
pushl %ebp | |
movl %esp, %ebp | |
movl $0, %eax # Index | |
movl 8(%ebp), %ecx # Address of str | |
strlen_loop: | |
movb (%ecx,%eax,1), %dl # Current char | |
cmpb $0, %dl | |
je strlen_end | |
incl %eax | |
jmp strlen_loop | |
strlen_end: | |
movl %ebp, %esp | |
popl %ebp | |
ret | |
.section .rodata | |
newline_char: | |
.ascii "\n" | |
space_char: | |
.ascii " " | |
.section .text | |
# ************************************ | |
# * echo [STRING]... | |
# * Prints the string(s) to stdout. | |
# ************************************ | |
.globl _start | |
_start: | |
movl %esp, %ebp | |
# Local variables (offset from %ebp) | |
.equ index, -4 # Stack index being operated on | |
.equ address, -8 # Current arg address | |
.equ length, -12 # Current arg length | |
subl $12, %esp | |
# Start at index 1 (this skips argc) | |
movl $1, index(%ebp) | |
echo_loop: | |
# Set address local variable | |
movl index(%ebp), %ecx | |
movl 4(%ebp, %ecx, 4), %eax | |
movl %eax, address(%ebp) | |
# Check if we're done (reached a NULL pointer) | |
cmpl $0, address(%ebp) | |
je echo_loop_end | |
# Calculate length of string | |
pushl address(%ebp) | |
call strlen | |
addl $4, %esp | |
# Set length local variable | |
movl %eax, length(%ebp) | |
# Print leading space if index > 1 | |
cmpl $1, index(%ebp) | |
jle leading_space_end | |
movl $space_char, %ecx | |
movl $1, %edx | |
leading_space_end: | |
# Print current argument | |
movl address(%ebp), %ecx | |
movl length(%ebp), %edx | |
incl index(%ebp) | |
jmp echo_loop | |
echo_loop_end: | |
# Print newline char | |
movl $newline_char, %ecx | |
movl $1, %edx | |
# Exit | |
movl $1, %eax | |
movl $0, %ebx | |
int $0x80 |
Hi @blk10-droid, this implementation only supports echo
's most basic functionality, displaying the arguments. There is no support for command line flags like -e
.
To use newlines, e.g., with a bash shell, you can use ANSI-C Quoting.
./echo $'Multiple\nlines\nin\noutput'
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This program works very well, but when I ./echo -e "Multiple\nlines\nin\noutput" the \n newline doesn't work