SECTION .text align=1
space: db ' '
nl: db 0x0A
version_text:
db "echo (pegasus' utils) version 3", 0x0A
db 'Written by The Almighty Pegasus Epsilon.', 0x0A
db 0x0A
db 'This bad boy is a whopping 731 bytes.', 0x0A
db 0x0A
db 'Copyright (C) 2005 Pegasus Epsilon', 0x0A
db 'Distribute Unmodified.', 0x0A
version_len: equ $-version_text
usage:
db 'Usage: '
usage_len: equ $-usage
help_text:
db ' [OPTION]... [STRING]...', 0x0A
db 'Echo the STRING(s) to standard output.', 0x0A
db 0x0A
db ' -n', 0x09, 0x09, ' do not output the trailing '
db 'newline', 0x0A
; not implemented
;
; db ' -e',0x09,0x09,' enable interpretation of the '
; db 'backslash-escaped characters',0x0A
; db 0x09,0x09,' listed below',0x0A
; db ' -E',0x09,0x09,' disable interpretation of those '
; db 'sequences in STRINGs',0x0A
;
; not implemented
db ' --help', 0x09, ' display this help and exit', 0x0A
db ' --version output version information and '
db 'exit', 0x0A
db 0x0A
; not implemented
;
; db 'Without -E, the following sequences are recognized and '
; db 'interpolated:',0x0A,0x0A
; db ' \NNN the character whose ASCII code is NNN
; db '(octal)',0x0A
; db ' \\ backslash',0x0A
; db ' \a alert (BEL)',0x0A
; db ' \b backspace',0x0A
; db ' \c suppress trailing newline',0x0A
; db ' \f form feed',0x0A
; db ' \n new line',0x0A
; db ' \r carriage return',0x0A
; db ' \t horizontal tab',0x0A
; db ' \v vertical tab',0x0A,0x0A
;
; not implemented
db 'Report bugs to <pegasus@pimpninjas.org>.', 0x0A
help_len: equ $-help_text
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
global _start
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
_start:
inc ebx ; select stdout
pop eax ; argc
pop edi ; save our name for --help
pop ecx ; argv[1] (first argument)
test ecx, ecx ; if there are no args, then
jz short finish_bounce ; print newline and exit
dec eax ; if eax was not two
dec eax ;
jnz short long_flags.end ; don't parse long flags
long_flags:
cmp word [ecx], '--' ; if it's not '--'
jne short long_flags.end ; skip -- code, otherwise
help:
cmp dword [ecx+2], 'help' ; if it's not '--help'
jne short .end ; skip --help code, otherwise
cmp byte [ecx+6], 0 ; if it's not '--help(null)'
jne short .end ; skip --help code, otherwise
mov ecx, usage ; print "Usage: "
mov dl, usage_len ;
mov al, 4 ; write()
int 0x80 ; go!
mov ecx, edi ; print our name
xor edx, edx ; clear edx
.strlen:
test byte [ecx+edx], ~0 ; if this byte is null, then
jz short .print ; print it, otherwise
inc edx ; increment counter, and
jmp short .strlen ; keep looking
.print:
mov al, 4 ; write()
int 0x80 ; go!
mov ecx, help_text ; print help text
mov edx, help_len ;
xor eax, eax ; write()
mov al, 4 ;
int 0x80 ; go!
jmp short long_flags.exit
help.end:
version:
cmp dword [ecx+2], 'vers' ; if it's not '--vers'
jne short .end ; skip --version code, otherwise
cmp dword [ecx+6], 0x006E6F69
; if it's not '--version(null)'
jne short .end ; skip --version code, otherwise
.print:
mov ecx, version_text ; print version text
mov dl, version_len ;
mov al, 4 ; write()
int 0x80 ; go!
long_flags.exit:
jmp short exit
version.end:
finish_bounce:
jmp short finish
long_flags.end:
short_flags:
cmp byte [ecx], '-' ; if the first byte is not a dash
jne short_flags.end ; it is not a flag
.n:
cmp word [ecx+1], 0x006E ; if it's not '-n'
jne short .n.end ; skip -n code, otherwise
.n.found:
xor esi, esi ; don't print newline
dec esi ;
pop ecx ; ready next arg
test ecx, ecx ; if it's null
jz short exit ; exit, otherwise
jmp short short_flags ; check the next flag
.n.end:
short_flags.end:
strlen:
test byte [ecx+edx], ~0 ; if this byte is null, then
jz short print ; print, otherwise
inc edx ; increment pointer, and
jmp short strlen ; keep looking
print:
mov al, 4 ; write()
int 0x80 ; go!
xor edx, edx ; clear edx
pop edi ; check next arg
test edi, edi ; if it's null, then
jz short finish ; finish up and exit
print_space:
mov ecx, space ; print space
inc edx ; one byte long
xor eax, eax ; write()
mov al, 4 ;
int 0x80 ; go!
dec edx ; clear edx
mov ecx, edi ; ready next arg
jmp short strlen ; do it again
finish:
mov ecx, nl ; print newline
mov edx, esi ; check ebp
inc edx ; -1 + 1 == 0, 0 + 1 == 1 :)
xor eax, eax ; write()
mov al, 4 ;
int 0x80 ; go!
exit:
mov al, 1 ; _exit()
dec ebx ; with no error
int 0x80 ; go!
end: