Hi,
Ok, I am understanding the code you wrote. He is the code again with newline added. See if I did this right:
; Get the program arguments from the stack which are (in order):
; number of arguments, program name, arg 1, arg 2, and so on
section .text
global _start
_start:
pop ecx ; Get the number of arguments
add ecx, '0' ; convert to a ascii number
push ecx ; push the result into memory using the stack
mov ecx, esp ; move the address of the stack pointer to ecx for sys_write
mov eax,4 ; Function 4 - write"
mov ebx,1 ; to stdout
mov edx,1 ; buffer size
int 80h
pop ecx ; Dump number of args from stack
call newline ; Print a newline
; stacks - each 'pop' gives the value of the next item in the stack
; if there are no more items in the stack, it returns null
nextarg:
pop ecx ; get pointer to string
; Comment by Frank Kotler:
; we could have kept "argc", and used it as a loop counter
; but args pointers are terminated with zero (dword),
; so if we popped a zero, we're done (environment variables follow this)
test ecx, ecx ; or "cmp ecx, 0" - Check if we reached the end of our string
jz exit
; now we need to find the length of our (zero-terminated) string
xor edx, edx ; or "mov edx, 0" ; Initialize edx to zero
getlen:
cmp byte [ecx + edx], 0 ; Take each byte and see if it is a terminated string (0x00h) or null
jz gotlen ; If the previous instruction found the terminated string, jump out of our loop
inc edx ; Nope, point to the next character or byte
jmp getlen ; and check again with getlen procedure
gotlen:
; now ecx -> string, edx = length
mov eax,4 ; Function 4 - write"
mov ebx,1 ; to stdout
int 80h ; call sys_write
call newline ; Print a newline charaction by calling our newline function
jmp nextarg ; Process the next argument
newline:
; Frank: probably want to print a newline here, "for looks"
; Here is my solution to newline:
mov edx, 10 ; Move 'newline' character into edx
push edx ; Put it into the stack
mov ecx, esp ; Put the current stack pointer into ecx for sys_write
mov eax,4 ; sys_write
mov ebx,1 ; stdout
mov edx,1 ; Only one character to print out
int 80h ; call sys_write
pop edx ; Don't need newline anymore, get rid of it so stack pointer points to what it was before
ret
exit:
mov eax,1
mov ebx,0
int 80h ; Exit
I think this somewhat completes my mission to create some assembler code to print command line arguements. Although, in DOS assembler it takes much less steps:
; DOS .com program, compile with nasm -f bin <program.asm>
; no linker required :-)
; sample from http://en.wikipedia.org/wiki/Program_Segment_Prefix
org 100h
; int 21h subfunction 9 requires '$' to terminate string
xor bx, bx
mov bl, [80h]
mov byte [bx + 81h], '$'
; print the string
mov ah, 9
mov dx, 81h
int 21h
; exit
mov ax, 4C00h
int 21h
But learning this the hard way was much more interesting as you can see and understand the steps it takes to create code like this.
Thanks very much for the help Frank. I'll be using this forum a lot for getting help on learning assembly.
Questions:
1: How large is the stack? Can I keep on pushing until I run out of memory?
2: How much data can you put in a register? Can I do "mov ecx, '<1024 bytes of data>' "? If ecx is a 32-bit register, then I am guessing 4 bytes?
qiet72