global asm_main
asm_main:
push ebp
mov ebp, esp
pop ebx ; pop argc
pop ebx ; pop argv[0]
pop ebx ; pop argv[1]
Ahhhh... If "asm_main" is being passed to ld as "--entrypoint", you've got argc, arg[0](name), arg[1](first parameter, if any), ...
However! You've pushed ebp, so your first pop is just getting ebp back, second pop would be argc... However! This looks like it might have been called by a C startup stub (Dr. Carter's tut?)... in which case you've popped the return address (doesn't matter, since you "sys_exit" instead of "ret"ing). Lord knows what the next pop will fetch...
What *I* would do, is to replace "asm_main" with "_start" (ld's default entrypoint). Assemble as usual, but you'll need to tell ld where to find the "right" dynamic linker (ld gets it wrong, by default - gcc knows...):
ld -o myprog myprog.o -I/lib/ld-linux.so.2 -lc
(by default, ld looks for .so.1 which results in a "file not found" when you do ./myprog - most puzzling!)
Also, drop the push ebp/mov ebp/esp... Start right with the pops. The first pop will be argc - you may wish to check this, to see if the user entered any parameters. There will be at least one - the program name. The next pop will be that - you'll probably discard it. The next pop should be (pointer to) "argument". As an alternative to checking argc, you can check this for non-zero... really "should" make sure we've got an argument, before we try to print it. From there on, I think you've got it right. You can just push ebx/push fmt - no *need* to put 'em in separate registers. (I'd do the add esp, 8 immediately after call printf, for clarity...)
If this is, in fact, called by Dr. Carter's driver.c... all bets are off. Lessee... "main" is called by crt0... stack would be return (to crt0) address... pushed ebp... a local variable "ret_ status" (who knows what gcc allows for a single dword), return (to main) address, your pushed ebp... You don't want to do this by poppin' stuff!!! Try something like mov ebx, [ebp + ???]... increase ??? by four until you find it. :)
You've got a linefeed (10) in your format string. Good. As an experiment, try removing it... "Hello World" will print *before* "argument"! Printf doesn't actually print anything until its internal buffer is flushed - either by a linefeed, or by exit. Just a tip...
Best,
Frank