Ich würde mit diesem OS/X Syscall tutorial beginnen (Der 64-Bit-Teil in Ihrem Fall). Es ist für NASM-Syntax geschrieben, aber die wichtige Information ist der Text und die Links für die SYSCALL Aufrufkonvention. Die SYSCALL Tabelle ist auf dieser Apple webpage gefunden. Weitere Informationen zur Standard-Aufrufkonvention für 64-Bit-OS/X finden Sie in der System V 64-bit ABI.
Von Bedeutung für SYSCALL Konvention:
- Argumente werden geführt, um über diese Register RDI, rsi, RDX, r10, r8 und r9
- syscall Nummer im rax Register
- der Anruf erfolgt über die syscall Anweisung
- was OS X trägt zum Mix ist, dass Sie 0x200000 hinzufügen müssen 00 an die syscall Nummer (müssen noch herausfinden, warum)
Sie haben viele Probleme mit mit Ihrem sys_read
Systemaufruf. Die SYSCALL Tabelle sagt dies:
3 AUE_NULL ALL { user_ssize_t read(int fd, user_addr_t cbuf, user_size_t nbyte); }
die Aufrufkonvention So gegeben ist int fd
in RDI, user_addr_t cbuf
(Zeiger auf Zeichenpuffer zu halten Daten zurück) in RSI und user_size_t nbyte
(maximale Bytes Puffer enthalten kann) ist in RDX.
Ihr Programm seg auf dem ret
bemängelt, weil Sie nicht die richtige Funktion Epilog hatte die Funktion Prolog an der Spitze zum Spiel:
push %rbp #
mov %rsp,%rbp # Function prologue
Sie müssen die Rückwärts am Boden tun, um das Ergebnis Code eingestellt in RAX und dann tun Sie die ret
. Etwas wie:
mov %rbp,%rsp # \ Function epilogue
pop %rbp #/
xor %eax, %eax # Return value = 0
ret # Return to C runtime which will exit
# gracefully and return to OS
Ich habe andere kleinere Bereinigung, aber versucht, die Struktur des Codes ähnlich zu halten. Sie müssen mehr Assembly lernen, um den Code besser zu verstehen, der RSI mit der Adresse für sys_read
SYSCALL einrichtet. Sie sollten versuchen, ein gutes Tutorial/Buch über x86-64 Assemblerprogrammierung im Allgemeinen zu finden. Einen Grund zu diesem Thema zu schreiben, sprengt den Rahmen dieser Antwort.
Code, der näher sein könnte, was Sie für die Suche die oben berücksichtigt:
.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
# for temp local variables
movl $0x2, -4(%rbp) # Number for comparison
# 16-bytes from -20(%rbp) to -5(%rbp)
# for char input buffer
movl $0x2000003, %eax
mov $0, %edi # 0 for STDIN
lea -20(%rbp), %rsi # Address of temporary buffer on stack
mov $16, %edx # Read 16 character maximum
syscall
movb (%rsi), %r10b # RSI = pointer to buffer on stack
# get first byte
subb $48, %r10b # Convert first character to number 0-9
cmpb -4(%rbp), %r10b # Did we find magic number (2)?
jne L2 # If No exit with error message
L1: # If the magic number matched print
# Hello World
xor %rax, %rax
movl $0x2000004, %eax
movl $1, %edi
movq [email protected](%rip), %rsi
movq $14, %rdx
syscall
jmp L0 # Jump to exit code
L2: # Print "Nope"
xor %eax, %eax
movl $0x2000004, %eax
movl $1, %edi
movq [email protected](%rip), %rsi
movq $6, %rdx
syscall
L0: # Code to exit main
mov %rbp,%rsp # \ Function epilogue
pop %rbp #/
xor %eax, %eax # Return value = 0
ret # Return to C runtime which will exit
# gracefully and return to OS