//----------------------------------------------------------------- // myargcat.s // // This program writes the concentenation of its command-line // arguments to the standard output device, and then writes a // ascii control-code to the standard error device. // // assemble using: $ as myargcat.s -o myargcat.o // and link using: $ ld myargcat.o -o myargcat // then run using: $ ./myargcat ... // // programmer: ALLAN CRUSE // written on: 06 APR 2008 //----------------------------------------------------------------- .equ sys_exit, 1 .equ sys_write, 4 .equ STDOUT, 1 .equ STDERR, 2 .section .text newln: .ascii "\n" # newline control-code .section .text _start: # loop through the array of command-line arguments xor %esi, %esi # initialize array-index nxarg: # check for end-of-arguments cmpl $0, 8(%esp, %esi, 4) # check: NULL pointer? je fini # yes, end of the list # otherwise, write argument to standard output mov $sys_write, %eax # system-call ID-number mov $STDOUT, %ebx # device-file ID-number mov 8(%esp, %esi, 4 ), %ecx # address of the string mov %ecx, %edx # copy string's address nxinc: cmpb $0, (%edx) # check: end-of-string? je noinc # yes, end of the scan inc %edx # else advance address jmp nxinc # and check next byte noinc: sub %ecx, %edx # compute byte count int $0x80 # invoke kernel service inc %esi # advance array index jmp nxarg # and check next arg fini: # write a newline to the standard error device mov $sys_write, %eax # system-call ID-number mov $STDERR, %ebx # device-file ID-number lea newln, %ecx # address of message mov $1, %edx # length of message int $0x80 # invoke kernel service #terminate this application mov $sys_exit, %eax # system-call ID-number xor %ebx, %ebx # use 0 as return-code int $0x80 # invoke kernel service .global _start # make entry-point visible .end # nothing more to assemble