日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++内嵌汇编 教程1

發布時間:2024/8/1 c/c++ 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++内嵌汇编 教程1 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Python微信訂餐小程序課程視頻

https://edu.csdn.net/course/detail/36074

Python實戰量化交易理財系統

https://edu.csdn.net/course/detail/35475
注:本文的所有代碼是在我自己的VS2008中測試的,由于環境的差別,不能保證能在所有的編譯器上運行。

1.內嵌匯編介紹

在C++中,可以通過__asm關鍵字來嵌入匯編語言。例如

int main(){\_\_asm{//匯編!mov eax,0}return 0; }

2.匯編版本Hello, World!

我們知道,在C++中,可以使用printf函數來輸出。(如果使用cout,需要使用運算符重載等技術,在這里反而不方便)

提示:匯編中,調用函數的指令叫做CALL。函數的參數是保存在棧中的。

那么我們可以開始寫了。首先,先看看C++正常版本的:

#include #includeconst char *s1="Hello, World\n",*s2="pause"; int main(){printf(s1);system(s2);return 0; }

為了方便,我們先把正常版本反匯編一下,結果是:

printf(s1); 00BD13CE mov esi,esp 00BD13D0 mov eax,dword ptr [s1 (0BD7038h)] 00BD13D5 push eax 00BD13D6 call dword ptr [\_\_imp\_\_printf (0BD82C4h)] 00BD13DC add esp,4 00BD13DF cmp esi,esp 00BD13E1 call @ILT+315(\_\_RTC\_CheckEsp) (0BD1140h)

第一句,mov esi,esp 為了后面檢查棧是否正常用第二句,mov eax,dword ptr[s1] 括號中的0BD7038h是地址,不要管他,意思是把地址放到eax中去第三句,push eax 把剛才放進eax的地址放入棧, 實際就是把參數放入棧

第四句,call dword ptr [__imp__printf]__imp__printf是printf函數編譯后的結果,下劃線開頭表示這是一個函數我們平時寫內聯匯編的時候直接寫printf即可

第五句,add esp,4其實是手動平棧,之前往棧里面放了4字節的s1,現在把esp指針也就是棧頂指針下移(棧從高地址往低地址),平棧

最后兩句不管它,就是保證esi和esp相等,因為之前手動平了棧,結合第一句,這里應該是相等的,不寫應該也沒事

最終的內聯匯編應該是這樣:

#include #includeconst char *s1="Hello, World\n",*s2="pause"; int main(){\_asm{mov eax,dword ptr [s1]push eaxcall dword ptr [printf]add esp,4mov eax,dword ptr[s2]push eaxcall dword ptr [system]add esp,4}return 0; }

運行結果正常。

3.內聯匯編A+B

A+B問題,同時需要使用scanf和printf

首先注意一點,函數的參數在棧中是倒著存放的。(注:這個C標準沒有規定,但是匯編語言本身就是非常依賴環境的一個東西,所以暫且不管它)

例如

scanf("%d %d",&a,&b);

如果翻譯成匯編,應該是這樣(下面的是偽代碼)

push &b push &a push "%d %d" call scanf

然后我們就可以開始寫了。

scanf的部分,注意最前面兩個參數,由于放入的是地址,所以不能使用MOV指令而是要使用LEA指令

lea eax,[a]

表示把a的地址放入eax中。

其他部分沒有什么難度,注意最后平棧的時候,add esp到底加上多少,加上的是每個參數的大小相加。

例如scanf,每個都是4字節的地址,總共就是12字節。

完整代碼

#include #includeconst char *s1="%d%d",*s2="%d\n",*s3="pause"; int a,b; int main(){\_asm{lea eax,[b]push eaxlea eax,[a]push eaxmov eax,dword ptr [s1]push eaxcall dword ptr [scanf]add esp,12mov eax,[a]add eax,[b]push eaxmov eax,dword ptr [s2]push eaxcall dword ptr [printf]add esp,8mov eax,dword ptr [s3]push eaxcall dword ptr [system]add esp,4}return 0; }

總結

以上是生活随笔為你收集整理的C++内嵌汇编 教程1的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。