亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++內(nèi)嵌匯編示例詳解

 更新時間:2022年01月20日 17:08:35   作者:計算機知識雜談  
這篇文章主要介紹了C++內(nèi)嵌匯編,本文的所有代碼是在我自己的VS2008中測試的,由于環(huán)境的差別,不能保證能在所有的編譯器上運行,需要的朋友可以參考下

匯編語言

匯編語言是一種功能很強的程序設(shè)計語言,也是利用了計算機所有硬件特性并能直接控制硬件的語言。在匯編語言中,用助記符(Memoni)代替操作碼,用地址符號(Symbol)或標(biāo)號(Label)代替地址碼。這樣用符號代替機器語言的二進(jìn)制碼,就把機器語言變成了匯編語言。

匯編語言比機器語言易于讀寫、調(diào)試和修改,同時也具有機器語言執(zhí)行速度快、占用內(nèi)存空間少等優(yōu)點。但在編寫復(fù)雜程序時,相對高級語言來說匯編語言代碼量較大,而且匯編語言依賴于具體的機型,不能通用,因此不能直接在不同處理機型之間移植。雖然其移植性不好,但效率非常高,針對計算機特定硬件而編制的匯編語言程序,能準(zhǔn)確地發(fā)揮計算機硬件的功能和特長,程序精煉而質(zhì)量高,所以匯編語言至今仍是一種常用而強有力的底層開發(fā)語言。

匯編語言的特點

匯編語言指令使用一些具有相應(yīng)含義的助憶符來表達(dá)的,所以,它要比機器語言容易掌握和運用。但因為要直接使用CPU資源,所以相對高級程序設(shè)計語言來說它又顯得相對復(fù)雜。匯編語言程序歸納起來大概有以下幾個主要特點。

  1. 與硬件相關(guān):匯編語言指令是指機器指令的一種符號表示,而不同類型的CPU有不同的機器指令系統(tǒng),也就有不同的匯編語言,所以匯編語言程序與機器有著密切的關(guān)系。也就是說,不同型號的CPU之間是無法通用相同匯編代碼的,因此導(dǎo)致匯編語言的移植性和通用性降低,這是匯編語言天生的缺陷。

  2. 保持了機器語言的優(yōu)點,具有直接和簡捷的特點:正因為匯編語言有“與機器相關(guān)性”的特性,程序員用匯編語言編寫程序時,可充分發(fā)揮自己的聰明才智,對機器內(nèi)部的各種資源進(jìn)行合理的安排,讓它們始終處于最佳的使用狀態(tài),這樣做的最終效果就是程序的執(zhí)行代碼短,執(zhí)行速度快,所以,匯編語言是高效的程序設(shè)計語言。另外匯編語言可有效地訪問、控制計算機的各種硬件設(shè)備,如磁盤、存儲器、CPU、I/O端口等,實現(xiàn)資源利用的最大化。

  3. 編寫程序復(fù)雜:匯編語言是一種面向機器的語言,其匯編指令與機器指令基本上一一對應(yīng),所以,匯編指令也同機器指令一樣既有功能單一、具體的特點。要想完成某件工作,就必須安排CPU的每步工作。另外,在編寫匯編語言程序時,還要考慮具體機型的限制、匯編指令的細(xì)節(jié)和限制等。

  4. 經(jīng)常與高級語言配合使用,應(yīng)用十分廣泛:在某些情況下,比如直接操作CPU執(zhí)行中斷以實現(xiàn)線程調(diào)度、保存CPU寄存器以存儲/恢復(fù)線程狀態(tài)等,僅僅使用高級語言是完不成的,需要借助于匯編語言,但是僅使用匯編語言的話,大型程序恐怕需要付出比高級語言幾倍的工作量,有時候也是沒有必要的。因此,可以在高級語言里嵌入?yún)R編語句,讓僅僅一部分需要高效率的代碼用匯編語言來完成,其余的框架搭建等用高級語言來完成,這樣既保證了效率又降低了代碼的復(fù)雜程度。這種配合使用在大型軟件開發(fā)里經(jīng)常遇到,應(yīng)用十分廣泛。

注:
本文的所有代碼是在我自己的VS2008中測試的,由于環(huán)境的差別,不能保證能在所有的編譯器上運行。

1.內(nèi)嵌匯編介紹

在C++中,可以通過__asm關(guān)鍵字來嵌入?yún)R編語言。
例如

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

2.匯編版本Hello, World!

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

提示:
匯編中,調(diào)用函數(shù)的指令叫做CALL。
函數(shù)的參數(shù)是保存在棧中的。

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

#include<stdio.h>
#include<stdlib.h>

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

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

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 把剛才放進(jìn)eax的地址放入棧, 實際就是把參數(shù)放入棧

第四句,call dword ptr [__imp__printf]
__imp__printf是printf函數(shù)編譯后的結(jié)果,下劃線開頭表示這是一個函數(shù)
我們平時寫內(nèi)聯(lián)匯編的時候直接寫printf即可

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

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

最終的內(nèi)聯(lián)匯編應(yīng)該是這樣:

#include<stdio.h>
#include<stdlib.h>

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

運行結(jié)果正常。

3.內(nèi)聯(lián)匯編A+B

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

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

例如

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

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

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

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

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

lea eax,[a]

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

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

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

完整代碼

#include<stdio.h>
#include<stdlib.h>
const char *s1="%d%d",*s2="%d\n",*s3="pause";
int a,b;
int main(){
    _asm{
        lea eax,[b]
        push eax
        lea eax,[a]
        push eax
        mov eax,dword ptr [s1]
        push eax
        call dword ptr [scanf]
        add esp,12
        mov eax,[a]
        add eax,[b]
        push eax
        mov eax,dword ptr [s2]
        push eax
        call dword ptr [printf]
        add esp,8
        mov eax,dword ptr [s3]
        push eax
        call dword ptr [system]
        add esp,4
    }
    return 0;
}

到此這篇關(guān)于C++內(nèi)嵌匯編的文章就介紹到這了,更多相關(guān)C++內(nèi)嵌匯編內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)帶頭雙向循環(huán)鏈表的示例詳解

    C++實現(xiàn)帶頭雙向循環(huán)鏈表的示例詳解

    這篇文章主要介紹了如何利用C++實現(xiàn)帶頭雙向循環(huán)鏈表,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-12-12
  • 聊聊C++ 運算符重載知識

    聊聊C++ 運算符重載知識

    運算符重載是一種形式的C++多態(tài),重載運算符可以使代碼看起來更加自然,下面通過例子介紹下C++ 運算符重載知識,感興趣的朋友一起看看吧
    2021-11-11
  • c++制作的時間函數(shù)類

    c++制作的時間函數(shù)類

    本文給大家分享的是一個個人使用C++編寫的時間函數(shù)類,主要是實現(xiàn)了類的定義和調(diào)用,相比較來說還算比較復(fù)雜的時間類了,推薦給小伙伴們,有需要的朋友可以參考下。
    2015-03-03
  • C++ vector類的模擬實現(xiàn)方法

    C++ vector類的模擬實現(xiàn)方法

    這篇文章主要介紹了C++ vector類的模擬實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 最新評論