2011-04-07 29 views
1

所以我的作業,我在Ubuntu上運行它,它編譯得很好,並按照它應該的方式運行。但是,當我在Mac OSX中運行它時,會出現總線錯誤。這是爲什麼?爲什麼我的程序在Ubuntu gcc上運行,但不是OSX gcc?

我與gcc -m32 source.c -o test

這裏編譯年代的Mac OSX版(加前綴下劃線):

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

char phrase[] = "slow but sure"; 
int sz; 
int phrasesz; 
char *arg; 
char *result; 

// Add any extra variables you may need here. 

int main(int argc, char* argv[]) { 
    if (argc != 2) { 
    printf("Usage: %s takes 1 string argument.\n", argv[0]); 
    exit(1); 
    } 

    // Allocate memory and copy argument string into arg. 

    sz = strlen(argv[1]) + 1; 
    arg = malloc(sz); 
    strcpy(arg, argv[1]); 

    // Allocate lots of memory for the result. 

    phrasesz = strlen(phrase) + 1; 
    result = malloc(sz * phrasesz); 

    // Now copy phrase into result, while replacing SPACE 
    // with SPACE+arg+SPACE. 

__asm__("\n\ 
    leal _phrase, %esi\n\ 
    movl _result, %ebx\n\ 
outerLoop:\n\ 
    cmpb $0, (%esi)\n\ 
    je  finished\n\ 
forLoop:\n\ 
    cmpb $32,(%esi)\n\ 
    je  endLoop\n\ 
    cmpb $0, (%esi)\n\ 
    je  finished\n\ 
    mov  (%esi), %eax\n\ 
    mov  %eax, (%ebx)\n\ 
    incl %ebx\n\ 
    incl %esi\n\ 
    jmp  forLoop\n\ 
endLoop:\n\ 
    mov  (%esi), %eax\n\ 
    mov  %eax, (%ebx)\n\ 
    incl %ebx\n\ 
    incl %esi\n\ 
    movl _arg, %edx\n\ 
copyArgv1IntoResult:\n\ 
    cmpb $0, (%edx)\n\ 
    je  finishedCopyingArgv1\n\ 
    mov  (%edx), %ecx\n\ 
    mov  %ecx, (%ebx)\n\ 
    incl %ebx\n\ 
    incl %edx\n\ 
    jmp  copyArgv1IntoResult\n\ 
finishedCopyingArgv1:\n\ 
    movb $32, (%ebx)\n\ 
    incl %ebx\n\ 
    jmp  outerLoop\n\ 
finished:\n\ 
    movb $0, (%ebx)\n\ 
"); 

    printf("%s\n", result); 
    return 0; 
} 

更新:

我跑了它在gdb調試器,這是我得到的錯誤。

Program received signal EXC_BAD_ACCESS, Could not access memory. 
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000 
0x00001ee8 in finished() 
1: x/i $pc 0x1ee8 <finished+11>: mov (%eax),%eax 

此外,我正在刪除Ubuntu版本,所以滾動較少。

+0

它只是說「總線錯誤」,當我運行它。 – Strawberry 2011-04-07 03:33:39

回答

1

你的一些指令,像...

mov  (%esi), %eax 

...正在複製比從字符緩衝區一次一個字節以上。我認爲這是偶然的?你最好在C中編寫代碼,然後使用gcc -S並與你的手寫代碼進行比較。即使緩衝區與字邊界對齊,您也會將指針遞增一個字節,因此一定要嘗試進行未對齊的內存讀取。一個sigbus基本上意味着你試圖從一個地址讀取一個單詞的內存值,該地址指向一個不在一個對齊的單詞開頭的字節,但是有些CPU如果緩慢地戰鬥,而另一些則會保留下來。我不知道主機之間的硬件差異。