2014-10-03 59 views
0

問題是,當程序步入行:stosb時,它將顯示一個錯誤:「程序接收到的信號SIGSEGV,分段錯誤。我不知道爲什麼,有什麼想法?gcc中的擴展asm:執行「stosb」時的分段錯誤

在ubuntu x86_64下,使用「gcc -o test test.c」進行編譯和鏈接。

#include <stdio.h> 

static inline char * strcpy(char * dest,const char *src) 
{ 
    int d0, d1, d2; 
    __asm__ __volatile__("1:\tlodsb\n\t" 
         "stosb\n\t" 
         "testb %%al,%%al\n\t" 
         "jne 1b" 
         : "=&S" (d0), "=&D" (d1), "=&a" (d2) 
         : "0" (src),"1" (dest) 
         : "memory"); 
    return dest; 
} 

int main(void) { 
    char* src_main = "Hello_src"; 
    char* dest_main = "Hello_des"; 
    strcpy(dest_main, src_main); 
    puts(src_main); 
    puts(dest_main); 
    return 0; 
} 

enter image description here

回答

1

的問題是,你想覆蓋的內存只讀部分,其中literal "Hello_des"的字符串存儲。不要這樣做。

的解決方案是使目標陣列,它是可寫的:

char dest_main[32] = "Hello_des"; 

當然,人們不禁要問爲什麼你寫的代碼,這是非常沒有意義的初始化字符串,然後立即strcpy()另一字符串在它上面。

+0

謝謝。這只是一個練習。我是新擴展裝配。 – Searene 2014-10-03 12:48:49

1

不要爲目的地使用字符串文字 - 字符串文字通常存儲在只讀部分,即它們實際上是const。更改:

char* dest_main = "Hello_des"; 

到:

char dest_main[] = "Hello_des"; 

或者只是:

char dest_main[16];