女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

在C中使用匯編程序的原因是?

jf_78858299 ? 來(lái)源:匯編語(yǔ)言 ? 作者:匯編語(yǔ)言 ? 2023-04-04 15:00 ? 次閱讀

現(xiàn)今,完全用匯編書寫的程序是非常少的。編譯器能很好地將高級(jí)語(yǔ)言轉(zhuǎn)換成有效的機(jī)器代碼。因?yàn)橛酶呒?jí)語(yǔ)言書寫代碼非常容易,所以高級(jí)語(yǔ)言變得很流行。此外,高級(jí)語(yǔ)言比匯編語(yǔ)言更容易移植!

當(dāng)使用匯編語(yǔ)言時(shí),我們經(jīng)常將它使用在代碼中的一小部分上。有兩種使用匯編語(yǔ)言的方法:在C中調(diào)用匯編子程序或內(nèi)嵌匯編。內(nèi)嵌匯編允許程序員把匯編語(yǔ)句直接放入到C代碼中。這樣是非常方便的;但是,內(nèi)嵌匯編同樣存在缺點(diǎn)。匯編語(yǔ)言的書寫格式必須是編譯器使用的格式。目前沒有一個(gè)編譯器支持NASM格式。不同的編譯器要求使用不同的格式。Borland和Microsoft要求使用MASM格式。DJGPP和Linux中g(shù)cc要求使用GAS格式。在PC機(jī)上,調(diào)用匯編子程序是更標(biāo)準(zhǔn)的技術(shù)。

在C中使用匯編程序通常是因?yàn)橐韵聨讉€(gè)原因:

1、需要直接訪問計(jì)算機(jī)的硬件特性,而用C語(yǔ)言很難或不可能做到。

2、程序執(zhí)行必須盡可能地快,而且相比于編譯器,程序員手動(dòng)優(yōu)化的代碼更好。

最后一個(gè)原因不像它以前一樣有根據(jù)。因?yàn)檫@些年編譯器技術(shù)提高了,而且編譯器通??梢援a(chǎn)生非常有效的代碼(特別是當(dāng)開啟編譯器優(yōu)化的時(shí)候)。調(diào)用匯編程序的缺點(diǎn):可移植性和可讀性減弱了。

絕大部分的C調(diào)用約定已經(jīng)確定了。但是,還需要描述一些額外的特征。

保存寄存器

首先, C假定子程序保存了下面這幾個(gè)寄存器的值:EBX,ESI,EDI, EBP,CS,DS,SS,ES。這并不意味著不能在子程序內(nèi)部修改它們。相反,它表示如果子程序改變了它們的值,那么在子程序返回之前必須恢復(fù)它們的原始值。EBX,ESI和EDI的值不能被改變,因?yàn)镃將這些寄存器用于寄存器變量。通常都是使用堆棧來(lái)保存這些寄存器的原始值。

函數(shù)名

大多數(shù)C編譯器都在函數(shù)名和全局或靜態(tài)變量前附加一個(gè)下劃線字符。例如,函數(shù)名f將指定為_f。因此,如果這是一個(gè)匯編程序,那么它必須標(biāo)記為_f,而不是f。Linux gcc編譯器并不附加任何字符。在可執(zhí)行的Linux ELF下,對(duì)于C函數(shù)f,你只需要簡(jiǎn)單使用函數(shù)名f即可。但是,DJGPP的gcc卻附加了一個(gè)下劃線。注意,在匯編程序skeleton中(圖1.7),主程序函數(shù)名是_asm main。

傳遞參數(shù)

按照C調(diào)用約定,一個(gè)函數(shù)的參數(shù)將以一定順序壓入棧中,這個(gè)順序與它們出現(xiàn)在函數(shù)調(diào)用里的順序相反??紤]這條C語(yǔ)句:printf("x = %d\\n",x); 圖4.11展示了如何編譯這條語(yǔ)句(用等價(jià)的NASM格式)。圖4.12展示了執(zhí)行完printf函數(shù)的開始部分后,堆棧的狀態(tài)。printf函數(shù)一個(gè)可以攜帶任意個(gè)參數(shù)的C語(yǔ)言庫(kù)函數(shù)。C調(diào)用約定的規(guī)則就是專門為允許這些類型的函數(shù)而規(guī)定的。因?yàn)閒ormat字符串的地址最后壓入堆棧,所以不管有多少參數(shù)傳遞到函數(shù),

圖片

計(jì)算局部變量的地址

找到定義在data或bss段的變量的地址是非常容易的?;旧?,連接程序做的就是這件事情。但是,要計(jì)算出在堆棧上的一個(gè)局部變量(或參數(shù))的地址就不簡(jiǎn)單了??墒?,當(dāng)調(diào)用子程序的時(shí)候,這種需求是非常普通的??紤]傳遞一個(gè)變量(讓我們稱它為x)的地址到一個(gè)函數(shù)(讓我們稱它為foo)的情況。如果x處在堆棧的EBP ? 8的位置,你不可以這樣使用:

mov       eax, ebp - 8

為什么?因?yàn)橹噶頜OV儲(chǔ)存到EAX里的值必須能由匯編器計(jì)算出來(lái)(也就是說(shuō),它最后必須是一個(gè)常量)。但是,有一條指令能做這種需求的計(jì)算。它就是LEA (即Load Effective Address,載入有效地址)。下面的代碼就能計(jì)算出x的地址并將它儲(chǔ)存到EAX中:

lea         eax, [ebp - 8]

現(xiàn)在EAX中存有了x的地址,而且當(dāng)調(diào)用函數(shù)foo的時(shí)候,就可以將其壓入到棧中。不要搞混了,這條指令看起來(lái)是從[EBP-8]中讀數(shù)據(jù);然而,這并不正確。LEA指令永遠(yuǎn)不會(huì)從內(nèi)存中讀數(shù)據(jù)。它僅僅計(jì)算出一個(gè)將會(huì)被其它指令使用到的地址,然后將這個(gè)地址儲(chǔ)存到它的第一個(gè)操作數(shù)里。因?yàn)樗]有實(shí)際讀內(nèi)存,所以不指定內(nèi)存大小(例如:dword)是必須的或說(shuō)是允許的。

返回值

返回值不為空的C函數(shù)執(zhí)行完后會(huì)返回一個(gè)值。C調(diào)用約定規(guī)定了這個(gè)要如何去做。返回值需通過寄存器傳遞。所有的整形類型(char,int,enum,等)通過EAX寄存器返回。如果它們小于32位,那么儲(chǔ)存到EAX的時(shí)候,它們將被擴(kuò)展成32位。(它們?nèi)绾螖U(kuò)展取決于是有符號(hào)類型還是無(wú)符號(hào)類型。) 64位的值通過EDX:EAX寄存器對(duì)返回。浮點(diǎn)數(shù)儲(chǔ)存在數(shù)學(xué)協(xié)處理器中的ST0寄存器中。(這個(gè)寄存器將在浮點(diǎn)數(shù)這一章來(lái)討論。)

其它調(diào)用約定

所有的80x86 C編譯器中都支持上面描述的標(biāo)準(zhǔn)C調(diào)用約定的規(guī)則。通常編譯器也支持其它調(diào)用約定。當(dāng)與匯編語(yǔ)言進(jìn)行接口時(shí),知道編譯器調(diào)用你的函數(shù)時(shí)使用的是什么調(diào)用約定是非常重要的。通常,缺省時(shí),使用的是標(biāo)準(zhǔn)的調(diào)用約定;但是,并不總是這一種情況4。使用多種約定的編譯器通常都擁有可以用來(lái)改變?nèi)笔〖s定的命令行開關(guān)。它們同樣提供擴(kuò)展的C語(yǔ)法來(lái)為單個(gè)函數(shù)指定調(diào)用約定。但是,各個(gè)編譯器的這些擴(kuò)展標(biāo)準(zhǔn)可以是不一樣的。

GCC編譯器允許不同的調(diào)用約定。一個(gè)函數(shù)的調(diào)用約定可以通過擴(kuò)展語(yǔ)法attribute 明確指定。例如,要聲明一個(gè)返回值為空的函數(shù)f,它帶有一個(gè)int參數(shù),使用標(biāo)準(zhǔn)調(diào)用約定,需使用下面的語(yǔ)法來(lái)聲明它的原型:

void   f ( int ) _attribute_(( cdecl ));

GCC同樣支持標(biāo)準(zhǔn)call 調(diào)用約定。通過把cdecl替換成stdcall,上面的函數(shù)可以指定為使用這種約定。stdcall約定和cdecl約定的不同點(diǎn)是stdcall要求子程序?qū)?shù)移除出棧(和Pascal調(diào)用約定一樣)。因此,stdcall調(diào)用約定只能使用在帶有固定參數(shù)的函數(shù)上(也就是說(shuō),不可以是函數(shù)printf和scanf)。

GCC同樣支持稱為regparm 的約定,這種約定告訴編譯器前3個(gè)整形參數(shù)通過寄存器傳遞給函數(shù),而不是通過堆棧。這是許多編譯器支持的一個(gè)共同的優(yōu)化模式。

Borland和Microsoft使用一樣語(yǔ)法來(lái)聲明調(diào)用約定。它們?cè)贑代碼中加上關(guān)鍵字_cdecl和_stdcall。這些關(guān)鍵字用來(lái)修飾函數(shù)。在原型聲明中,它們出現(xiàn)在函數(shù)名的前面例如,上面的函數(shù)f用Borland和Microsoft定義如下:

void _cdecl f ( int );

每種調(diào)用約定都有各自的優(yōu)缺點(diǎn)。cdecl調(diào)用約定的主要優(yōu)點(diǎn)是它非常簡(jiǎn)單而且非常靈活。它可以用于任何類型的C函數(shù)和C編譯器。使用其它約定會(huì)限制子程序的可移植性。它的主要缺點(diǎn)是與其它約定相比它執(zhí)行較慢而且使用更多的內(nèi)存(因?yàn)楹瘮?shù)的每次調(diào)用都需要用代碼將參數(shù)移除出

棧。)。

stdcall調(diào)用約定的主要優(yōu)點(diǎn)是相比于cdecl它使用較少的內(nèi)存。在CALL指令之后,不需要清理堆棧。它的主要缺點(diǎn)是它不能使用于可變參數(shù)的函數(shù)。

使用寄存器傳遞參數(shù)的調(diào)用約定的優(yōu)點(diǎn)是速度非??臁V饕秉c(diǎn)是這種約定太復(fù)雜。有些參數(shù)可能在寄存器中,而另一些可能在堆棧中。

在匯編程序中調(diào)用C函數(shù)

C與匯編接口的一個(gè)主要優(yōu)點(diǎn)是允許匯編代碼訪問大型C庫(kù)和用戶寫的函數(shù)。例如,如果你想調(diào)用一下scanf函數(shù)來(lái)從鍵盤讀一個(gè)整形,該怎么辦?圖4.14展示了完成這件事的代碼。需要記住的非常重要的一點(diǎn)就是scanf函數(shù)遵循字面意義的C調(diào)用標(biāo)準(zhǔn)。這就意味著它保存了EBX,ESI和EDI寄存器的值;但是,EAX,ECX和EDX寄存器的值可能會(huì)被修改。事實(shí)上,EAX肯定會(huì)被修改,因?yàn)樗鼘⒈4鎠canf調(diào)用的返回值。至于與C接口的其它例子,可以看用來(lái)產(chǎn)生asm io.obj的asm io.asm文件中的代碼。

圖片

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • PC機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    201

    瀏覽量

    29179
  • 匯編語(yǔ)言
    +關(guān)注

    關(guān)注

    14

    文章

    410

    瀏覽量

    36567
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1656

    瀏覽量

    49905
  • nasm
    +關(guān)注

    關(guān)注

    0

    文章

    2

    瀏覽量

    6930
收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    求幫忙寫個(gè)匯編程序!

    求大神幫忙寫一個(gè)匯編程序用匯編程序實(shí)現(xiàn)“行走的小人”這一程序的源代碼???
    發(fā)表于 09-26 22:49

    匯編程序中的常量怎么定義?

    ,并在程序初始化時(shí)加載到數(shù)組中。匯編程序文件使用數(shù)組的全局名稱來(lái)確定系數(shù)的開頭,并相應(yīng)地加載系數(shù)值。這一點(diǎn)讓我吃驚,因?yàn)橄禂?shù)只由匯編程序使用。有沒有一種簡(jiǎn)單的方法可以
    發(fā)表于 10-16 10:14

    Keil下完成一個(gè)匯編程序的編寫

    文章目錄要求一、Keil下完成一個(gè)匯編程序的編寫1、新建工程2、配置環(huán)境3、編譯測(cè)試(1)測(cè)試代碼(2)仿真器設(shè)置(3)編譯調(diào)試4、hex文件分析要求Keil下完成一個(gè)匯編程序的編
    發(fā)表于 08-11 08:04

    Keil下完成一個(gè)匯編程序的編寫

    Keil下完成一個(gè)匯編程序的編寫,學(xué)習(xí)動(dòng)態(tài)調(diào)試變量;并注意觀察最終生成hex文件的各段的大小,以及Hex文件前8個(gè)字節(jié)內(nèi)容,解釋其含義。(3)在上面Keil 匯編基礎(chǔ)上用匯編程序完成1~100 求和 (1+2+3+…+100)的
    發(fā)表于 12-20 07:43

    I2C匯編程序

    I2C匯編程序:/*****;FileName: IicSMasU.a51;Describe: 51 系列模擬I2C 總線主控器驅(qū)動(dòng)程序;Date: 2003/11/12
    發(fā)表于 03-02 23:38 ?35次下載

    51 系列匯編程序設(shè)計(jì)的優(yōu)化1

    51 系列匯編程序設(shè)計(jì)的優(yōu)化1
    發(fā)表于 05-15 14:55 ?24次下載

    如何在C程序中使用匯編

    怎樣C程序中使用匯編,如何在C程序
    發(fā)表于 09-23 23:43 ?55次下載

    KeilC51中C51程序匯編程序的接口方法

    C語(yǔ)言程序匯編語(yǔ)言程序的相互調(diào)用可視為函數(shù)的調(diào)用,只不過此函數(shù)是采用不同語(yǔ)言編寫。C
    發(fā)表于 07-09 17:49 ?74次下載

    PCF8563匯編程序

    剛寫的一個(gè)PCF8563匯編程序,請(qǐng)教高手?。。?***************************************************************;PCF8563時(shí)鐘
    發(fā)表于 08-19 17:41 ?90次下載

    匯編程序100例

    匯編程序100例,方便初學(xué)者快速的入門,加快掌握匯編語(yǔ)言。
    發(fā)表于 11-17 15:22 ?97次下載

    AD和DA轉(zhuǎn)換的c程序和對(duì)應(yīng)的匯編程序

    有關(guān)AD和DA轉(zhuǎn)換的c程序和對(duì)應(yīng)的匯編程序
    發(fā)表于 11-19 16:43 ?27次下載

    MSP430 C匯編程序

    MSP430 C匯編程序,有需要的朋友下來(lái)看看。
    發(fā)表于 05-25 10:26 ?22次下載

    DSP匯編程序優(yōu)化方法的探討

    DSP匯編程序優(yōu)化方法的探討
    發(fā)表于 10-20 10:41 ?5次下載
    DSP<b class='flag-5'>匯編程序</b>優(yōu)化方法的探討

    lcd1602匯編程序,LCD1602匯編顯示程序代碼

    匯編語(yǔ)言書寫的程序翻譯成與之等價(jià)的機(jī)器語(yǔ)言程序的翻譯程序。匯編程序輸入的是用匯編語(yǔ)言書寫的源
    發(fā)表于 10-20 15:34 ?1.5w次閱讀
    lcd1602<b class='flag-5'>匯編程序</b>,LCD1602<b class='flag-5'>匯編</b>顯示<b class='flag-5'>程序</b>代碼

    C中直接使用匯編語(yǔ)句進(jìn)行編程

    ? 一、gcc 內(nèi)聯(lián)匯編 內(nèi)聯(lián)匯編即在C中直接使用匯編語(yǔ)句進(jìn)行編程,使程序可以
    的頭像 發(fā)表于 11-16 09:26 ?8848次閱讀