2012-11-18 51 views
2

所以,首先,這是我正在幫助的一個朋友的任務,雖然從我完成C開始已經有一段時間了,但這不是問題(或者至少是我不認爲是),問題是彙編代碼。該分配必須使用以內聯彙編編寫的函數對用戶輸入後傳遞給該函數的兩個數進行求和,然後返回該值,然後輸出該值。在運行我的代碼時,我遇到了錯誤,無論是讀取還是寫入到asm函數中找到的內存位置,尤其是第二個mov命令,程序在嘗試執行該代碼行時都會掛起。跟蹤程序,其中一個值將被正確存儲(無論用戶輸入的第二個值是什麼,我認爲這是正常的,因爲值是在彙編中反向讀取的),另一個完全不被讀取,程序崩潰。我花了大約四個小時試圖弄清楚這一點,現在正在尋求外部幫助。無論如何,足夠的背景,試圖徹底,這是代碼。我確定我正在做的事情可能是一些基本的東西,並正在盯着我,但任何幫助表示讚賞。哦,是的,我確保masm在視覺工作室中啓用。用於Visual Studio調用的內聯彙編器

#include "stdafx.h" 
#include "stdio.h" 
#include <conio.h> 

int sum(int val1, int val2); 
int main (void) 
{ 
int val1=0, val2=0, val3=0; 

printf("Hello, this program will add two whole numbers. Please enter the first number.\n"); 
scanf("%d",&val1); 

printf("Please enter the second number.\n"); 
scanf("%d",&val2); 

val3 = sum(val1, val2); 
printf("The sum of %d and %d is %d", val1, val2, val3); 
_getch(); 

return 0; 
} 

int sum (int val1, int val2){ 
int val3; 

    __asm{ mov eax, val2  ; 
      push eax    ; 
      mov ebx, val1  ; 
      push ebx    ; 
      add eax, ebx   ; 
      mov ecx, val3  ; 
      pop val3    ; 
      pop ebx    ; 
      pop eax    ; 
      pop ecx    ; 
      ret     ; 
    } 
    return val3; 

} 
+2

如果你「推」兩次並彈出四次,那看起來不正確。在同一個函數中你不能同時擁有'ret'和'return'。 –

+0

http://www.unknowncheats.me/forum/c-and-c/67864-msvc-converting-function-__declspec-naked.html – Goz

回答

3

我不知道什麼都推和持久性有機污染物是的,但這個工程:

int sum (int val1, int val2) 
{ 
    int val3; 

    __asm{ mov eax, val2  ; 
      mov ebx, val1  ; 
      add eax, ebx   ; 
      mov val3, eax  ; 
     } 
    return val3; 
} 
+0

這實際上做得很好,心靈的解釋是什麼?有一些非常相似的東西,根本沒有工作。推and和砰砰聲是我在經過幾個小時的挫折之後變得聰明。原來的代碼實際上與你所得到的幾乎完全相同,只是爲了學習壽命! – user1834288

+0

他將堆棧管理完全交給編譯器......編譯代碼並檢查生成的彙編器... – Goz

+0

我的原始版本幾乎與此相同,只有val1先移入註冊表中,而不是val2,顯然是這樣有所作爲!那是因爲它們被傳遞給函數的順序? – user1834288

0

有沒有必要使用推送和加載CPU寄存器時彈出。按下指令會將該值寫入SS:[ESP]寄存器對指向的存儲器位置,其中SS是16位堆棧段,ESP是32位堆棧指針。這也通過操作數的大小以字節爲單位減少ESP。 pop指令執行反操作,從SS所指向的內存位置讀取:[ESP],並按操作數的大小以字節爲單位遞增ESP。

+0

在x86保護模式下(在Windows下運行的情況下),_SS_實際上是一個16位選擇器(不像在實模式/ vm8086等中看到的那樣)用於索引LGDT或GDT。 –