[英]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.