2016-11-20 72 views
0

所以我一直用C寫的ç內聯彙編生成未處理的異常

int transform (char * p) 
{ 
    if(*p!='-'){ 
     return 0; 
    } 

    p++; 
    if(*p == 'a') 
    { 
     return 1; 
    } 
    else if(*p == 'b') 
    { 
     return 2; 
    } 
    else 
    { 
     return 0; 
    } 
} 

這個功能,我試着翻譯它內聯彙編IA32這樣

int trasform (char * p) 
    { 
     int result; 
     _asm 
     { 
      mov eax, p 
      mov ebx, 0 
      mov bl, [eax] 
      cmp bl, '-' ; 
       jne invalid 
       mov bl, [4*eax] 
      cmp bl, 'a' 
       jne isB 
       mov result, 1 
       mov eax, result 
      jmp out 
    isB: 
      cmp bl, 'b' 
       jne invalid 
       mov result, 2 
       mov eax, result 
      jmp out 
    invalid: 
      mov result, 0 
      mov eax, result 
    out: ; end 

    } 
    return result; 
} 

當我有寫在功能C在Visual Studio中完美工作,但是當我將其更改爲內聯彙編並執行代碼時,出現錯誤說明

proyect.exe中0x774e15ee未處理的異常:0xC0000005:訪問衝突讀取位置0x01745388。

這個問題必須與代碼或視覺工作室的問題嗎?

我調試我的代碼,發現誤差在這一行

mov bl, [4*eax] 
+0

如何調用'transform'?我質疑在'p ++'之後解引用'p'的合法性。 – Bathsheba

+0

@Bathsheba在主函數中,我收到一個命令參數-b或-a,所以我調用transform函數來查看我收到的參數是否有效。 arg = argv [3];然後int op = transform(arg); – ravelinx

+1

Visual Studio允許您一次執行一條指令來調試代碼(如果我正確記得,按F11)。這將指向一個產生異常的特定指令。請編輯你的文章並寫下這條指令 - 這是解決你的問題的非常重要的信息! – anatolyg

回答

1

作爲調試器所表示的,問題是在該指令:

mov bl, [4*eax] 

在C代碼尋找,其意圖是字符串的第二個字節加載到bl。指向第一個字節的指針是eax,所以指向第二個字節的指針是eax+1。也就是說,正確的命令是

mov bl, [eax+1] 

或者,你可以做到這一點與兩個指令:

inc eax 
mov bl, [eax] 

這是更符合C代碼行:

p++; 
if (*p == ...) 

,但確實的相同。

3
mov bl, [4*eax] 
cmp bl, 'a' 

的想法是超前的指針EAX。不需要繁殖!

inc eax    ;ptr++ 
mov bl, [eax] 
cmp bl, 'a' 
1

您想要讀取' - '後面的字節,它將在eax+1處,而不是4*eax處。