2012-10-15 2 views
1

Mac OS X 용 GNU 어셈블러에 Hello World를 쓰려고하는데 "Hello World"를 인쇄하기 전에 버스 오류가 발생했습니다.Hello World/gas/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)으로 인해 Apple에 버그 리포트를 제출했습니다. 그들은 대신 clang을 사용한다고 말했습니다.

내가 뭘 잘못하고 있니?

사양 :

  • ld64-134.9
  • 연타 4.1
  • 엑스 코드 4.5
  • 맥 OS X 10.8.2
  • 맥북 프로 2009 대답에

답변

2

에 어떤 네가 잘못 했어. 잘 모르겠다. 어셈블리를 사용한 이후로 꽤 오래되었습니다.하지만 clang은 내 Mac에서 .equ statmentes를 좋아하지 않았습니다. 내가 그들을 바꿨을 때, 괜찮 았어. (솔직히 내가 macports에서 하나를 사용하지만, NASM을 선호합니다.)

나는 clang으로 컴파일 할 간단한 .s 파일을 만들었습니다. 문자열 길이가 하나의 문제가 있습니다. (아마도 버그입니다. ?) $ 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 내 어셈블리 환경을 설정하는 방법을 보거나 zip 파일을 업로드 한 Mac 용 범용 바이너리를 만드는 방법을보고 싶다면 모든 코드가 공용 도메인에 있습니다 (https : // docs.google.com/open?id=0B49KRMcMpMV1MnhqMzZVOHBfeFE) –