2010-11-06 143 views
1

我已經在這裏問過類似的問題,但我仍然有一些錯誤,所以我希望你能告訴我我做錯了什麼。只知道我知道彙編程序,並且我已經在8051彙編程序中完成了幾個項目,甚至它也不一樣,接近於x86彙編程序。一些內嵌彙編程序問題

有塊中的代碼我在VC++ 2010速成嘗試(我想從CPUID指令信息):`

int main() 
{ 
char a[17]; //containing array for the CPUID string 
a[16] = '\0'; //null termination for the std::cout 
void *b=&a[0]; 
int c=0; //predefined value which need to be loaded into eax before cpuid 

_asm 
{ 
    mov eax,c; 
    cpuid; 
    mov [b],eax; 
    mov [b+4],ebx; 
    mov [b+8],ecx; 
    mov [b+12],edx; 
} 
std::cout<<a; 
}` 

所以,快速總之,我試圖創建無效指針第一數組的元素,而不是使用間接尋址只是從寄存器中移動數值。但是這種方法給了我「堆棧變量b損壞的運行時錯誤」,但我不知道爲什麼。

請幫忙。謝謝。這只是爲了學習的目的,我知道有CPUID功能....

編輯:另外,你怎麼能在x86 VC++ 2010內聯彙編程序中使用直接尋址?我的意思是8051中即時數字加載的通用語法是mov src,#number,但是在VC++ asm中它的mov dest,number沒有#號。那麼如何告訴編譯器你想直接訪問內存單元地址x?

+1

你根本不需要c。只需使用'xor eax,eax'來設置eax = 0。 – TonyK 2010-11-29 15:11:24

回答

6

您的堆棧損壞的原因是因爲您將eax的值存儲在b中。然後將ebx的值存儲在存儲位置b+4等處。如果b是字節指針,則內聯彙編程序語法[b+4]等同於C++表達式&(b+4)

你可以看到這個,如果你看b和單步。只要您執行mov [b],eax,值b就會改變。要解決這個問題

一種方法是的b值加載到索引寄存器和使用索引尋址:

mov edi,[b] 
mov [edi],eax 
mov [edi+4],ebx 
mov [edi+8],ecx 
mov [edi+12],edx 

你並不真的需要b可言,指針堅持a。您可以直接與lea(加載有效地址)指令加載索引寄存器:

lea edi,a 
mov [edi],eax 
... etc ... 

如果您正在使用內聯彙編擺弄,它是在調試器中打開寄存器窗口,看世事如何變遷是個好主意當你單腳踩。

您也可以直接尋址存儲器:

mov dword ptr a,eax 
mov dword ptr a+4,ebx 
... etc ... 

然而,直接解決諸如比需要更多的代碼字節索引前面例子中解決。

我認爲上述與lea(負載有效地址)指令和我展示的直接尋址解答您的最終問題。

0

在調試器中打開「寄存器」窗口的建議,觀察事物如何變化無法在VC++ 2010 Express中運行。

你可能會和我一樣驚訝,發現VC++ 2010 Express是MISSING寄存器窗口。自從進行拆卸工作以來,這一點特別令人驚訝。

我知道的唯一解決方法是打開一個觀察窗口並在名稱字段中輸入註冊名稱。輸入EAX EBX ECX EDX ESI EDI EIP ESP EBP EFL和CS DS ES SS FS GS如果需要

ST1 ST2 ST3 ST4 ST5 ST6 ST7也可以在監視窗口中工作。

您可能還希望通過右鍵單擊監視窗口並檢查十六進制顯示來將值設置爲十六進制。