Re: Problems with FreeBSD assembly
On Wed, 11 Nov 2009 14:43:21 -0500, David Jackson wrote: > I am having great difficulty running a very simple assembler program > on FreeBSD on x86 in my efforts to learn some assembly programming on > FreeBSD. I have tried to compile the following with nasm, however i > get nothing in response when I attempt to run this program: > >section .data >hello db 'Hello, World!', 0xa >hbytes equ $ - hello > >section .text >global _start >_start: >pushdword hbytes >pushdword hello >pushdword 1 >mov eax,0x4 >int 0x80 >add esp,12 > >pushdword 0 >mov eax,0x1 >int 0x80 > > nasm -f elf -o hello1s.o hello1.s > ld -s -o hello1s hello1s.o > > ./hello1s prints nothing. > > What is wrong here? It should print "hello world". > Thanks in advance for your help, it is greatly appreciated. Hi David. The truss utility is your friend when you are trying to decipher system call problems. It can translate system call arguments to human-readable output; a very useful property when debugging issues like this. For example here's the output for your original code: $ truss ./hello write(134516904,0xe,1) ERR#9 'Bad file descriptor' process exit, rval = 1 Note how the arguments of write() are 'misplaced'? The answer is that you are not calling the system call with C-like conventions (including a function call return address). The calling conventions of system calls are described in the Developer's Handbook at: http://www.freebsd.org/doc/en/books/developers-handbook/x86-system-calls.html You are missing a dword push before interrupting. As the dev handbook says, you have to use C calling conventions or push an extra (ignorable) dword before interrupting: An assembly language program can do that as well. For example, we could open a file: | kernel: | int 80h ; Call kernel | ret | | open: | pushdword mode | pushdword flags | pushdword path | mov eax, 5 | callkernel | add esp, byte 12 | ret This is a very clean and portable way of coding. If you need to port the code to a UNIX system which uses a different interrupt, or a different way of passing parameters, all you need to change is the kernel procedure. But assembly language programmers like to shave off cycles. The above example requires a call/ret combination. We can eliminate it by pushing an extra dword: | open: | pushdword mode | pushdword flags | pushdword path | mov eax, 5 | pusheax ; Or any other dword | int 80h | add esp, byte 16 So by pushing *one* more dword before you interrupt should work fine (and it does, from a small test I ran just now): : keram...@kobe:/home/keramida$ cat hello.s : section .data : hello db 'Hello, World!', 0xa : hbytes equ $ - hello : : section .text : global _start : _start: : push dword hbytes : push dword hello : push dword 1 : push dword 0 ;or any other dword : mov eax, 4 : int 0x80 : add esp, byte 16 : : push dword 0 : push dword 0 ;ignored dword : mov eax, 1 : int 0x80 : add esp, byte 8 ;NOT REACHED : keram...@kobe:/home/keramida$ nasm -f elf -o hello.o hello.s : keram...@kobe:/home/keramida$ ld -s -o hello hello.o : keram...@kobe:/home/keramida$ truss ./hello : Hello, World! : write(1,"Hello, World!\n",14)= 14 (0xe) : process exit, rval = 0 : keram...@kobe:/home/keramida$ HTH, Giorgos ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "freebsd-questions-unsubscr...@freebsd.org"
Re: Problems with FreeBSD assembly
Charlie Kester wrote: On Wed 11 Nov 2009 at 17:32:41 PST Charlie Kester wrote: One more thing: Notice that the system call number (or any other dword) should also be pushed onto the stack before the int 80h. The reason for this is given at the top of the page: although the kernel is accessed using int 80h, it is assumed the program will call a function that issues int 80h, rather than issuing int 80h directly. So the extra dword pushed onto the stack takes the place of the return address from the function the kernel expects to have been called. And since you're not actually using as a return address, it doesn't matter what value it actually has. The kernel doesn't use it for anything; it just expects it to be there in a properly arranged stack frame. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "freebsd-questions-unsubscr...@freebsd.org" The push eax is what made it work. So that was the problem. Stdin and stdout do not need to opened before they are used, as in C. Thank you everyone for your help on this, that solved it. Here is the code that works: section .data hello db 'Hello, World!', 0xa hbytes equ $ - hello section .text global _start _start: pushdword hbytes pushdword hello pushdword 1 mov eax,0x4 push eax int 0x80 add esp,16 pushdword 0 mov eax,0x1 push eax int 0x80 ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "freebsd-questions-unsubscr...@freebsd.org"
Re: Problems with FreeBSD assembly
Mihai Don??u wrote: > I don't think the kernel is the one that initializes the > 0, 1 and 2 file descriptors (stdin, stdout and stderr). Correct so far. > I think you have to open them yourself ... No, the shell does it. That's how it is able to set up pipes and redirection. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "freebsd-questions-unsubscr...@freebsd.org"
Re: Problems with FreeBSD assembly
On Wed 11 Nov 2009 at 17:32:41 PST Charlie Kester wrote: One more thing: Notice that the system call number (or any other dword) should also be pushed onto the stack before the int 80h. The reason for this is given at the top of the page: although the kernel is accessed using int 80h, it is assumed the program will call a function that issues int 80h, rather than issuing int 80h directly. So the extra dword pushed onto the stack takes the place of the return address from the function the kernel expects to have been called. And since you're not actually using as a return address, it doesn't matter what value it actually has. The kernel doesn't use it for anything; it just expects it to be there in a properly arranged stack frame. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "freebsd-questions-unsubscr...@freebsd.org"
Re: Problems with FreeBSD assembly
On Wed 11 Nov 2009 at 11:43:21 PST David Jackson wrote: I am having great difficulty running a very simple assembler program on FreeBSD on x86 in my efforts to learn some assembly programming on FreeBSD. I have tried to compile the following with nasm, however i get nothing in response when I attempt to run this program: section .data hello db 'Hello, World!', 0xa hbytes equ $ - hello section .text global _start _start: pushdword hbytes pushdword hello pushdword 1 mov eax,0x4 int 0x80 add esp,12 pushdword 0 mov eax,0x1 int 0x80 nasm -f elf -o hello1s.o hello1.s ld -s -o hello1s hello1s.o ./hello1s prints nothing. What is wrong here? It should print "hello world". Thanks in advance for your help, it is greatly appreciated. http://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/x86.html You've seen this part of the handbook, yes? In particular: http://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/x86-system-calls.html Calling your attention to the example code shown just before section 11.3.2, which shows how to open a file: open: pushdword mode pushdword flags pushdword path mov eax, 5 pusheax ; Or any other dword int 80h add esp, byte 16 Notice that the system call number (or any other dword) should also be pushed onto the stack before the int 80h. So try this: pushdword hbytes pushdword hello pushdword 1 ; stdout mov eax,0x4 pusheax ; or any other dword int 0x80 add esp,16 ; don't forget to account for the extra dword! ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "freebsd-questions-unsubscr...@freebsd.org"
Re: Problems with FreeBSD assembly
On Wednesday 11 November 2009 21:43:21 David Jackson wrote: > I am having great difficulty running a very simple assembler program on > FreeBSD on x86 in my efforts to learn some assembly programming on > FreeBSD. I have tried to compile the following with nasm, however i get > nothing in response when I attempt to run this program: > > section .data > hello db 'Hello, World!', 0xa > hbytes equ $ - hello > > section .text > global _start > _start: > pushdword hbytes > pushdword hello > pushdword 1 > mov eax,0x4 > int 0x80 > add esp,12 > > pushdword 0 > mov eax,0x1 > int 0x80 > > nasm -f elf -o hello1s.o hello1.s > ld -s -o hello1s hello1s.o > > ./hello1s prints nothing. > I don't think the kernel is the one that initializes the 0, 1 and 2 file descriptors (stdin, stdout and stderr). I think you have to open them yourself. I will know for sure when my nasm port finishes installing. :) -- Mihai Donțu ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "freebsd-questions-unsubscr...@freebsd.org"
Problems with freebsd assembly
I am having great difficulty running a very simple assembler program on FreeBSD on x86 in my efforts to learn some assembly programming on FreeBSD. I have tried to compile the following with nasm, however i get nothing in response when I attempt to run this program: section .data hello db 'Hello, World!', 0xa hbytes equ $ - hello section .text global _start _start: pushdword hbytes pushdword hello pushdword 1 mov eax,0x4 int 0x80 add esp,12 pushdword 0 mov eax,0x1 int 0x80 nasm -f elf -o hello1s.o hello1.s ld -s -o hello1s hello1s.o ./hello1s prints nothing. What is wrong here? It should print "hello world". Thanks in advance for your help, it is greatly appreciated. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "freebsd-questions-unsubscr...@freebsd.org"
Problems with FreeBSD assembly
I am having great difficulty running a very simple assembler program on FreeBSD on x86 in my efforts to learn some assembly programming on FreeBSD. I have tried to compile the following with nasm, however i get nothing in response when I attempt to run this program: section .data hello db 'Hello, World!', 0xa hbytes equ $ - hello section .text global _start _start: pushdword hbytes pushdword hello pushdword 1 mov eax,0x4 int 0x80 add esp,12 pushdword 0 mov eax,0x1 int 0x80 nasm -f elf -o hello1s.o hello1.s ld -s -o hello1s hello1s.o ./hello1s prints nothing. What is wrong here? It should print "hello world". Thanks in advance for your help, it is greatly appreciated. ___ freebsd-questions@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-questions To unsubscribe, send any mail to "freebsd-questions-unsubscr...@freebsd.org"