2012-10-15 67 views
1

我想在GNU彙編器爲Mac OS X編寫Hello World,但它可以打印「Hello World」之前的總線錯誤。麻煩讓你好世界/天然氣/ Mac OS X的工作

hello.s

.global start 

.data 

.equ stdout, 1 

.equ sys_write, 4 
.equ sys_exit, 1 

.equ kernel, 0x80 

msg: .asciz "Hello World!\n" 
.equ len, .-msg 

.text 

start: 
    push $len 
    push $msg 
    push $stdout 
    mov $sys_write, %eax 
    sub $4, %esp 
    int $kernel 
    add $4 + $4 * $3, %esp 

    push $0 
    mov $sys_exit, %eax 
    sub $4, %esp 
    int $kernel 

跟蹤:

$ clang -c -o hello.o hello.s 
$ ld -o hello -macosx_version_min 10.6 hello.o 
$ ./hello 
Bus error: 10 

$ gdb hello 
(gdb) run 
Starting program: /Users/andrew/Desktop/src/mcandre/gas/hello/freebsd/hello 

Program received signal EXC_BAD_ACCESS, Could not access memory. 
Reason: KERN_PROTECTION_FAILURE at address: 0x0000000000002000 
0x0000000000002000 in msg() 

我立足我的代碼關閉的有兩件事情:

我從NASM/Mac OS X和Gas/Linux語法中提取了語義。

我也嘗試了GNU彙編程序維基百科page上的示例程序,但它也是總線錯誤。

我向蘋果提交了一個錯誤報告,因爲它的GNU彙編器過時了(如1.38)。他們說要改用clang。

我在做什麼錯?

規格:

  • ld64-134.9
  • 鐺4.1
  • 的Xcode 4.5
  • 的Mac OS X 10.8.2
  • 的MacBook Pro 2009年

回答

2

在回答什麼你做錯了,我不確定。自從我使用assembly以來已經有一段時間了,但是clang並不喜歡我Mac上的.equ statmentes。當我替換它時,它運行良好。 (說實話,我更喜歡NASM,儘管我使用的是macports。)

我創建了一個簡單的.s文件,它將與clang一起編譯,我有一個字符串長度問題.. (也許它是一個bug ?)我在哪裏存儲長度在$ len,但是當我使用$ len它不起作用..但使用硬編碼的數字。

我編寫的代碼:

clang -c -o hello.o hello.s -arch i386 
ld -o hello -macosx_version_min 10.6 -arch i386 hello.o 
./hello 

hello.s:

/* defines */ 
.set sys_exit, 1 
.set sys_write, 4 
.set stdout, 1 
.set kernel, 0x80 

// TEXT SECTION 
.text 

/* write function */ 
.macro write str, strSize 
    // length of string 
    push \strSize 
    // the string 
    push \str 
    // to file descriptor 
    push $stdout 
    // what we want to call 
    movl $sys_write, %eax 
    // call the kernal 
    call _syscall 
    // free the stack 
    addl $12, %esp 
.endm 

/* define main function */ 
.globl start 

/* impl. main function */ 
start: 

    // write(string, long) 
    // if I use $len i get a bunch of letters 
    write $msg, $14 //$len 

    // exit(0) 
    // if i print out $len it is 14 
    push $0 //$len 
    movl $sys_exit, %eax 
    call _syscall 

/* call kernal 
* 
* so you don't have to do sub $4, %esp 
*/ 
_syscall: 
    int $kernel 
    ret 

// DATA SECTION 
.data 
    /* our string */ 
    msg: .string "Hello World!\n" 
    // using len: .long $14 causes the same issue as . - msg 
    // where the string does not end at 14 
    // perhaps someone else knows why.. 
    len: .long . - msg 

我希望這有助於。

+0

任何我們可以得到'len'工作的方式? – mcandre

+0

以及我已經嘗試使用'$ -msg',然後是'。-msg',但是如果你想在* nix上有一個彙編環境,我可以在我的答案中添加一個我認爲更容易實現的工作示例;通過MacPorts和NASM。 –

+0

@mcandre如果你想看看我是如何設置我的程序集環境的,或者想看看如何爲mac創建一個通用的二進制文件,我已經上傳了一個zip文件,所有的代碼都在公共領域[link](https:// docs.google.com/open?id=0B49KRMcMpMV1MnhqMzZVOHBfeFE) –