From: Holger H. <ha...@gm...> - 2009-08-18 14:40:17
|
Hi all, i want to write 3 bytes of argv[0] on stdout but it doesn't work. Return code -14 (EFAULT Bad address). Am i missing something here? System is archlinux 2009.08 x86_64 kernel 2.6.31-rc6 nasm 2.05.01 Binutils 2.19.1.20090418 stdout equ 1 write equ 4 exit equ 1 section .text global _start _start: pop rax ; rax = argc pop rax ; rax = argv[0] mov rdx, 3 ; write 3 bytes mov rcx, rax ; rcx = rax = argv[0] mov rbx, stdout mov rax, write int 0x80 mov rbx, 0 mov rax, exit int 0x80 |
From: Frank K. <fbk...@zy...> - 2009-08-18 17:22:57
|
Holger Hanrath wrote: > Hi all, > > i want to write 3 bytes of argv[0] on stdout but it doesn't work. > Return code -14 (EFAULT Bad address). Am i missing something here? > > System is archlinux 2009.08 x86_64 kernel 2.6.31-rc6 > nasm 2.05.01 Binutils 2.19.1.20090418 > > > > stdout equ 1 > write equ 4 > exit equ 1 > > section .text > global _start > _start: > pop rax ; rax = argc > pop rax ; rax = argv[0] > > mov rdx, 3 ; write 3 bytes > mov rcx, rax ; rcx = rax = argv[0] > mov rbx, stdout > mov rax, write > int 0x80 > > mov rbx, 0 > mov rax, exit > int 0x80 64-bit does it a "bit" differently (from the late and sorely missed Chuck Crayne: section .data string1 db "Hello World!",10,0 section .text global _start _start: ; calculate the length of string mov rdi, string1 mov rcx, -1 xor al,al cld repnz scasb ; place the length of the string in RDX mov rdx, -2 sub rdx, rcx ; print the string using write() system call mov rsi, string1 push 0x1 pop rax mov rdi,rax syscall ; exit from the application here xor rdi,rdi push 0x3c pop rax syscall That won't do what you want, of course, but will give you an idea which registers are used. (the push/pop is just shorter - probably want to use "-Ox" to use it) I assume the stack is set up the same for 64-bit as for 32-bit(?). Let us know how it works - 64-bit examples are in short supply, still... Best, Frank |
From: Holger H. <ha...@gm...> - 2009-08-18 19:19:51
|
On Tue, 18 Aug 2009 13:22:01 -0400 Frank Kotler <fbk...@zy...> wrote: > Holger Hanrath wrote: > > Hi all, > > > > i want to write 3 bytes of argv[0] on stdout but it doesn't work. > > Return code -14 (EFAULT Bad address). Am i missing something here? > > > > System is archlinux 2009.08 x86_64 kernel 2.6.31-rc6 > > nasm 2.05.01 Binutils 2.19.1.20090418 > > > > > > > > stdout equ 1 > > write equ 4 > > exit equ 1 > > > > section .text > > global _start > > _start: > > pop rax ; rax = argc > > pop rax ; rax = argv[0] > > > > mov rdx, 3 ; write 3 bytes > > mov rcx, rax ; rcx = rax = argv[0] > > mov rbx, stdout > > mov rax, write > > int 0x80 > > > > mov rbx, 0 > > mov rax, exit > > int 0x80 > > 64-bit does it a "bit" differently (from the late and sorely missed > Chuck Crayne: > > section .data > string1 db "Hello World!",10,0 > > section .text > global _start > > _start: > ; calculate the length of string > mov rdi, string1 > mov rcx, -1 > xor al,al > cld > repnz scasb > > ; place the length of the string in RDX > mov rdx, -2 > sub rdx, rcx > > ; print the string using write() system call > mov rsi, string1 > push 0x1 > pop rax > mov rdi,rax > syscall > > ; exit from the application here > xor rdi,rdi > push 0x3c > pop rax > syscall > > That won't do what you want, of course, but will give you an idea which > registers are used. (the push/pop is just shorter - probably want to use > "-Ox" to use it) I assume the stack is set up the same for 64-bit as for > 32-bit(?). Let us know how it works - 64-bit examples are in short > supply, still... > > Best, > Frank Your example works fine thanks but i had no problems writing strings from the data section to stdout. I know that the rax register holds the right address after the second pop because i can copy the bytes i found there into a string in the data section and then write it to stdout like this: ;; copy argv[0] into str1 and write to stdout stdout equ 1 write equ 4 exit equ 1 section .data str1 db '#############',10,0 str1len equ $ - str1 section .text _copy: cmp BYTE [rax], 0 ; check if we reached the end of argv[0] je _print cmp rcx, rbx ; check if argv[0] is not to long je _print mov dl, [rax] ; move one byte into dl mov BYTE [str1+rbx], dl ; move one byte into str1 at pos of rbx inc rax ; move on in argv[0] inc rbx ; move on in str1 jmp _copy global _start _start: pop rax ; load argc pop rax ; load argv[0] xor rbx,rbx ; rbx = 0 mov rcx,str1len ; load str1len into rcx sub rcx,2 ; make sure we always wirte a new line xor dl,dl ; dl = 0 jmp _copy _print: mov rdx, str1len ; message length mov rcx, str1 ; message to write mov rbx, 1 ; file descriptor (stdout) mov rax, 4 ; system call number (sys_write) int 0x80 ; call kernel mov rbx, 0 ; return 0 mov rax, exit ; system call number (sys_exit) int 0x80 ; call kernel that works it's only when try to do the write with the memory address from the stack. I think i overlook something here but thanks for trying to help me. Holger |
From: Holger H. <ha...@gm...> - 2009-08-19 08:49:08
|
On Tue, 18 Aug 2009 21:19:21 +0200 Holger Hanrath <ha...@gm...> wrote: here is the program what that does what i want in native x86_64: ; write 3 bytes from argv[0] to stdout ; syscall numbers from asm/unistd_64.h stdout equ 1 write equ 1 exit equ 60 section .text global _start _start: pop rax ; rax = argc pop rax ; rax = argv[0] ; place the length of the string in RDX mov rdx, 3 ; write 3 bytes ; print the string using write() system call mov rsi, rax ; write needs the address of the string in rsi mov rdi, stdout mov rax, write syscall ; exit from the application here xor rdi, rdi ; return 0 mov rax, exit syscall |
From: H. P. A. <hp...@zy...> - 2009-08-19 16:51:48
|
On 08/19/2009 01:48 AM, Holger Hanrath wrote: > On Tue, 18 Aug 2009 21:19:21 +0200 > Holger Hanrath <ha...@gm...> wrote: > > > here is the program what that does what i want in native x86_64: > Yes, but inefficient. > ; write 3 bytes from argv[0] to stdout > ; syscall numbers from asm/unistd_64.h > stdout equ 1 > write equ 1 > exit equ 60 > > mov rax, write Small number... you probably want "mov eax,..." instead. etc. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. |
From: Holger H. <ha...@gm...> - 2009-08-19 17:56:28
|
On Wed, 19 Aug 2009 09:50:17 -0700 "H. Peter Anvin" <hp...@zy...> wrote: > On 08/19/2009 01:48 AM, Holger Hanrath wrote: > > On Tue, 18 Aug 2009 21:19:21 +0200 > > Holger Hanrath <ha...@gm...> wrote: > > > > > > here is the program what that does what i want in native x86_64: > > > > Yes, but inefficient. true > > ; write 3 bytes from argv[0] to stdout > > ; syscall numbers from asm/unistd_64.h > > stdout equ 1 > > write equ 1 > > exit equ 60 > > > > mov rax, write > > Small number... you probably want "mov eax,..." instead. from the AMD64 Abi: "3. The number of the syscall has to be passed in register %rax." Holger |
From: H. P. A. <hp...@zy...> - 2009-08-20 01:14:00
|
On 08/19/2009 10:56 AM, Holger Hanrath wrote: > > from the AMD64 Abi: > > "3. The number of the syscall has to be passed in register %rax." > Correct. Loading a value into eax clears the upper 32 bits of rax, however. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. |
From: Frank K. <fbk...@zy...> - 2009-08-19 17:11:41
|
H. Peter Anvin wrote: > On 08/19/2009 01:48 AM, Holger Hanrath wrote: >> On Tue, 18 Aug 2009 21:19:21 +0200 >> Holger Hanrath <ha...@gm...> wrote: >> >> >> here is the program what that does what i want in native x86_64: >> > > Yes, but inefficient. > >> ; write 3 bytes from argv[0] to stdout >> ; syscall numbers from asm/unistd_64.h >> stdout equ 1 >> write equ 1 >> exit equ 60 >> >> mov rax, write > > Small number... you probably want "mov eax,..." instead. > > etc. Or even: push write pop rax Smaller, if that's the goal, but slower (I think), and it doesn't do much for "readability", IMO. There's a tutorial here: <http://www.vikaskumar.org/wiki/index.php?title=X86-64_Tutorial> Might help... Best, Frank |
From: H. P. A. <hp...@zy...> - 2009-08-19 18:25:53
|
On 08/19/2009 10:11 AM, Frank Kotler wrote: > > Or even: > > push write > pop rax > > Smaller, if that's the goal, but slower (I think), and it doesn't do > much for "readability", IMO. > mov eax,... ... is even smaller (5 bytes.) -hpa |
From: Frank K. <fbk...@zy...> - 2009-08-19 18:42:56
|
H. Peter Anvin wrote: > On 08/19/2009 10:11 AM, Frank Kotler wrote: >> Or even: >> >> push write >> pop rax >> >> Smaller, if that's the goal, but slower (I think), and it doesn't do >> much for "readability", IMO. >> > > mov eax,... > > ... is even smaller (5 bytes.) I should have specified the "-Ox" switch, or "push byte write". Best, Frank |
From: H. P. A. <hp...@zy...> - 2009-08-19 20:19:54
|
On 08/19/2009 11:43 AM, Frank Kotler wrote: > H. Peter Anvin wrote: >> On 08/19/2009 10:11 AM, Frank Kotler wrote: >>> Or even: >>> >>> push write >>> pop rax >>> >>> Smaller, if that's the goal, but slower (I think), and it doesn't do >>> much for "readability", IMO. >>> >> mov eax,... >> >> ... is even smaller (5 bytes.) > > I should have specified the "-Ox" switch, or "push byte write". > Ah yes, that does work for values <= 127. It's really slow, though. -hpa |
From: H. P. A. <hp...@zy...> - 2009-08-19 06:35:10
|
On 08/18/2009 07:34 AM, Holger Hanrath wrote: > Hi all, > > i want to write 3 bytes of argv[0] on stdout but it doesn't work. > Return code -14 (EFAULT Bad address). Am i missing something here? > > System is archlinux 2009.08 x86_64 kernel 2.6.31-rc6 > nasm 2.05.01 Binutils 2.19.1.20090418 > > > > stdout equ 1 > write equ 4 > exit equ 1 > > section .text > global _start > _start: > pop rax ; rax = argc > pop rax ; rax = argv[0] > > mov rdx, 3 ; write 3 bytes > mov rcx, rax ; rcx = rax = argv[0] > mov rbx, stdout > mov rax, write > int 0x80 > > mov rbx, 0 > mov rax, exit > int 0x80 > int 0x80 is used for 32-bit system calls. 64 bits uses syscall, and entirely different system call numbers and a different calling convention. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. |
From: Holger H. <ha...@gm...> - 2009-08-19 07:25:00
|
On Tue, 18 Aug 2009 23:33:46 -0700 "H. Peter Anvin" <hp...@zy...> wrote: > On 08/18/2009 07:34 AM, Holger Hanrath wrote: > > Hi all, > > > > i want to write 3 bytes of argv[0] on stdout but it doesn't work. > > Return code -14 (EFAULT Bad address). Am i missing something here? > > > > System is archlinux 2009.08 x86_64 kernel 2.6.31-rc6 > > nasm 2.05.01 Binutils 2.19.1.20090418 > > > > > > > > stdout equ 1 > > write equ 4 > > exit equ 1 > > > > section .text > > global _start > > _start: > > pop rax ; rax = argc > > pop rax ; rax = argv[0] > > > > mov rdx, 3 ; write 3 bytes > > mov rcx, rax ; rcx = rax = argv[0] > > mov rbx, stdout > > mov rax, write > > int 0x80 > > > > mov rbx, 0 > > mov rax, exit > > int 0x80 > > > > int 0x80 is used for 32-bit system calls. 64 bits uses syscall, and > entirely different system call numbers and a different calling convention. i see that now thanks for pointing out Holger |
From: Holger H. <ha...@gm...> - 2009-08-19 18:08:12
|
On Wed, 19 Aug 2009 13:11:49 -0400 Frank Kotler <fbk...@zy...> wrote: > H. Peter Anvin wrote: > > On 08/19/2009 01:48 AM, Holger Hanrath wrote: > >> On Tue, 18 Aug 2009 21:19:21 +0200 > >> Holger Hanrath <ha...@gm...> wrote: > >> > >> > >> here is the program what that does what i want in native x86_64: > >> > > > > Yes, but inefficient. > > > >> ; write 3 bytes from argv[0] to stdout > >> ; syscall numbers from asm/unistd_64.h > >> stdout equ 1 > >> write equ 1 > >> exit equ 60 > >> > >> mov rax, write > > > > Small number... you probably want "mov eax,..." instead. > > > > etc. > > Or even: > > push write > pop rax > > Smaller, if that's the goal, but slower (I think), and it doesn't do > much for "readability", IMO. > > There's a tutorial here: > > <http://www.vikaskumar.org/wiki/index.php?title=X86-64_Tutorial> good link wish i had it earlier Holger |