2016-04-19 10 views
0

Ich habe schon seit einiger Zeit versucht, eine Nummer von einer Tastatur zu bekommen und sie mit einem Wert auf dem Stapel zu vergleichen. Wenn es korrekt ist, wird es "Hello World!" und wenn es falsch ist, sollte es "Nö!" ausdrucken. Wie auch immer, was jetzt passiert, ist egal, dass der Eingang "jne" aufgerufen wird, nein gedruckt wird und segfault. Vielleicht könnte einer von Ihnen eine Hand reichen.Tastatur speichern Eingabe in x64-Baugruppe (Mac OS/X)

.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 [email protected](%rip), %rsi 
    movq $14, %rdx    
    syscall 
    ret 

L2: 
    xor %eax, %eax 
    movl $0x2000004, %eax   
    movl $1, %edi     
    movq [email protected](%rip), %rsi 
    movq $6, %rdx     
    syscall 
    ret 

Antwort

1

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_readSYSCALL 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