2015-09-10 44 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!!!