簡體   English   中英

為什么osx 64-bit asm syscall segfault

[英]Why does osx 64-bit asm syscall segfault

我試圖在OSX上以匯編形式編寫一個x86-64的hello世界,但是每當我進行syscall編寫時,它都是段錯誤。 我已經嘗試過通過Gnu C內聯匯編進行等效的syscall,並且可以正常工作,所以我感到非常困惑:

        .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"

您的問題在於以下幾行:

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

請注意,使用at&t語法,如果要使用常量,則必須在常量前面加上$ (美元符號),否則就引用了內存地址。 沒有$符號,您的值就是直接的間接地址。

例如:

movq 0x2000004, %rax

嘗試將四字從內存地址0x2000004移出並將其放在%rax

您可能只需要修改代碼即可:

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

請注意,我在每個常量的開頭添加了一個美元符號。

在這種情況下,這是一個簡單的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!!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM