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 |