2015-09-10 42 views
1

我想在OSX上的程序集中編寫一個x86-64 hello world,但是每當我編寫一個系統調用時,它就會出現故障。我試圖通過GNU C內聯彙編相當於系統調用和它的作品,所以我徹底糊塗:爲什麼osx 64位asm系統調用段錯誤

 .section  __TEXT,__text,regular,pure_instructions 
     .globl _main 
     .align 4, 0x90 
_main: 
     .cfi_startproc 
     movq 0x2000004, %rax 
     movq 1, %rdi 
     leaq _hi(%rip), %rsi 
     movq 12, %rdx 
     syscall 

     xor %rax, %rax 
     ret 
     .cfi_endproc 

     .section  __DATA,__data 
     .globl _hi 
_hi: 
     .asciz "Hello world\n" 

這是基於折以下GNU C,這作品:

#include <string.h> 

int main() { 
    char *hw = "Hello World\n"; 
    unsigned long long result; 
    asm volatile ("movq %1, %%rax\n" 
     "movq %2, %%rdi\n" 
     "movq %3, %%rsi\n" 
     "movq %4, %%rdx\n" 
     "syscall\n" 
     : "=rax" (result) 
     : "Z" (0x2000004), 
     "Z" (1), 
     "r" (hw), 
     "Z" (12) 
     : "rax", "rdi", "rsi", "rdx"); 
} 

C編譯時生成以下asm:

 .section  __TEXT,__text,regular,pure_instructions 
     .globl _main 
     .align 4, 0x90 
_main:         ## @main 
     .cfi_startproc 
## BB#0: 
     pushq %rbp 
Ltmp2: 
     .cfi_def_cfa_offset 16 
Ltmp3: 
     .cfi_offset %rbp, -16 
     movq %rsp, %rbp 
Ltmp4: 
     .cfi_def_cfa_register %rbp 
     leaq L_.str(%rip), %rcx 
     movq %rcx, -8(%rbp) 
     ## InlineAsm Start 
     movq $33554436, %rax 
movq $1, %rdi 
movq %rcx, %rsi 
movq $12, %rdx 
syscall 

     ## InlineAsm End 
     movq %rcx, -16(%rbp) 
     xorl %eax, %eax 
     popq %rbp 
     ret 
     .cfi_endproc 

     .section  __TEXT,__cstring,cstring_literals 
L_.str:         ## @.str 
     .asciz "Hello World\n" 

回答

1

你的問題是這幾行:

movq 0x2000004, %rax 
movq 1, %rdi 
leaq _hi(%rip), %rsi 
movq 12, %rdx 

要知道,與& T語法,如果你想使用常量與您MUST前綴他們$(美元符號)否則您引用內存地址。如果沒有$符號,您的價值是直接的間接地址。

例如:

movq 0x2000004, %rax 

試圖從移動存儲地址0x2000004四字,並放置在%rax

你可能只需要修改代碼看起來像:我添加了一個美元符號每個常量開始

movq $0x2000004, %rax 
movq $1, %rdi 
leaq _hi(%rip), %rsi 
movq $12, %rdx 

通知。

0

這裏是一個簡單的64位「Hello World」(或Hello StackOverflow)。它應該建立在OSX之上。試試看:

section .data 
    string1 db 0xa, " Hello StackOverflow!!!", 0xa, 0xa, 0 
    len equ $ - string1 

section .text 
    global _start 

    _start: 
    ; write string to stdout 
     mov  rax, 1    ; set write to command 
     mov  rsi, string1  ; string1 to source index 
     mov  rdi, rax   ; set destination index to 1 (stdout) already in rax 
     mov  rdx, len   ; set length in rdx 
     syscall      ; call kernel 

     ; exit 
     xor  rdi,rdi    ; zero rdi (rdi hold return value) 
     mov  rax, 0x3c   ; set syscall number to 60 (0x3c hex) 
     syscall      ; call kernel 

; **Compile/Output** 
; 
;  $ nasm -felf64 -o hello-stack_64.o hello-stack_64.asm 
;  $ ld -o hello-stack_64 hello-stack_64.o 

;  $ ./hello-stack_64 
; 
;  Hello StackOverflow!!!