osx - Storing keyboard Input in x64 assembly (Mac OS/X) -
i have been trying time number keyboard , comparing value on stack. if correct print "hello world!" , if incorrect, should print out "nope!". however, happens no matter input "jne" called, nope printed, , segfault. perhaps 1 of lend hand.
.section __data,__data str: .asciz "hello world!\n" sto: .asciz "nope!\n" .section __text,__text .globl _main _main: push %rbp mov %rsp,%rbp sub $0x20, %rsp movl $0x0, -0x4(%rbp) movl $0x2, -0x8(%rbp) movl $0x2000003, %eax mov $0, %edi subq $0x4, %rsi movq %rsi, %rcx syscall cmp -0x8(%rbp), %edx je l1 jne l2 xor %rbx, %rbx xor %rax, %rax movl $0x2000001, %eax syscall l1: xor %rax, %rax movl $0x2000004, %eax movl $1, %edi movq str@gotpcrel(%rip), %rsi movq $14, %rdx syscall ret l2: xor %eax, %eax movl $0x2000004, %eax movl $1, %edi movq sto@gotpcrel(%rip), %rsi movq $6, %rdx syscall ret
i start os/x syscall tutorial (the 64-bit part in case). written nasm syntax important information text , links syscall calling convention. syscall table found on apple webpage. additional information on standard calling convention 64-bit os/x can found in system v 64-bit abi.
of importance syscall convention:
- arguments passed in order via these registers rdi, rsi, rdx, r10, r8 , r9
- syscall number in rax register
- the call done via syscall instruction
- what os x contributes mix have add 0x20000000 syscall number (still have figure out why)
you have many issues with sys_read
system call. syscall table says this:
3 aue_null { user_ssize_t read(int fd, user_addr_t cbuf, user_size_t nbyte); }
so given calling convention, int fd
in rdi, user_addr_t cbuf
(pointer character buffer hold return data) in rsi, , user_size_t nbyte
(maximum bytes buffer can contain) in rdx.
your program seg faulted on ret
because didn't have proper function epilogue match function prologue @ top:
push %rbp # mov %rsp,%rbp # function prologue
you need reverse @ bottom, set result code in rax , ret
. like:
mov %rbp,%rsp # \ function epilogue pop %rbp # / xor %eax, %eax # return value = 0 ret # return c runtime exit # gracefully , return os
i did other minor cleanup, tried keep structure of code similar. have learn more assembly better understand code sets rsi address sys_read
syscall . should try find tutorial/book on x86-64 assembly language programming in general. writing primer on subject beyond scope of answer.
code might closer looking takes above account:
.section __data,__data str: .asciz "hello world!\n" sto: .asciz "nope!\n" .section __text,__text .globl _main _main: push %rbp # mov %rsp,%rbp # function prologue sub $0x20, %rsp # allocate 32 bytes of space on stack # temp local variables movl $0x2, -4(%rbp) # number comparison # 16-bytes -20(%rbp) -5(%rbp) # char input buffer movl $0x2000003, %eax mov $0, %edi # 0 stdin lea -20(%rbp), %rsi # address of temporary buffer on stack mov $16, %edx # read 16 character maximum syscall movb (%rsi), %r10b # rsi = pointer buffer on stack # first byte subb $48, %r10b # convert first character number 0-9 cmpb -4(%rbp), %r10b # did find magic number (2)? jne l2 # if no exit error message l1: # if magic number matched print # hello world xor %rax, %rax movl $0x2000004, %eax movl $1, %edi movq str@gotpcrel(%rip), %rsi movq $14, %rdx syscall jmp l0 # jump exit code l2: # print "nope" xor %eax, %eax movl $0x2000004, %eax movl $1, %edi movq sto@gotpcrel(%rip), %rsi movq $6, %rdx syscall l0: # code exit main mov %rbp,%rsp # \ function epilogue pop %rbp # / xor %eax, %eax # return value = 0 ret # return c runtime exit # gracefully , return os
Comments
Post a Comment