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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

一步步编写操作系统 69 汇编语言和c语言共同协作 70

發(fā)布時(shí)間:2023/12/10 windows 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一步步编写操作系统 69 汇编语言和c语言共同协作 70 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

由于有了上一節(jié)的鋪墊,本節(jié)的內(nèi)容相對(duì)較少,這里給大家準(zhǔn)備了兩個(gè)小文件來(lái)實(shí)例演示匯編語(yǔ)言和c語(yǔ)言相互調(diào)用。

會(huì)兩種不同語(yǔ)言的人,只是掌握了同一件事物的兩種表達(dá)方式。人在學(xué)習(xí)一種新語(yǔ)言時(shí),潛意識(shí)里是建立了語(yǔ)言符號(hào)與事物形象的映射關(guān)系,比如我們?cè)趯W(xué)習(xí)grape這個(gè)單詞時(shí),我們之所以認(rèn)為它就是我們所認(rèn)知的葡萄,是因?yàn)槲覀冎肋@兩個(gè)名詞都是在描述同一種圓圓的、黑紫色、甜酸的這一水果的形象,如果腦子中不存在這個(gè)形象的話,不光是學(xué)不會(huì)grape這個(gè)英文單詞,就連中文的葡萄也不知道是何意??傊?#xff0c;對(duì)于具體的事物,一定是先有其形象,再有其描述,這樣才能理解該事物,了解了事物的本質(zhì)形象后,無(wú)論該事物的名字怎樣變化,我們都能將它們相互轉(zhuǎn)換。

也許有同學(xué)會(huì)問(wèn),以上這些所說(shuō)的目的是什么?各位觀眾稍安勿燥,馬上就要入戲啦^_^。

“匯編語(yǔ)言和C語(yǔ)言可以互相調(diào)用”,這句話并不是如表面陳述的那樣,似乎是兩種語(yǔ)言能直接交流,其實(shí)并不是這樣。c語(yǔ)言和匯編語(yǔ)言完全是不同的東西,它們?cè)趺茨苷J(rèn)識(shí)對(duì)方呢。這就像跟不懂漢語(yǔ)的人說(shuō)漢語(yǔ),那人聽了肯定會(huì)暈頭轉(zhuǎn)向的,除非身邊有個(gè)翻譯幫忙轉(zhuǎn)述,這個(gè)翻譯所做的工作實(shí)質(zhì)上是在腦子中找到這種語(yǔ)言所描述的事物形象,然后給出這種事物形象的另一種語(yǔ)言表達(dá),這個(gè)事物形象才是翻譯的核心。這有些類似上面提到的葡萄的例子,在同一種指令集上的各種計(jì)算機(jī)程序語(yǔ)言,最終也要編譯為那些相同的機(jī)器碼,這些機(jī)器碼便是高級(jí)語(yǔ)言的本質(zhì)形象。對(duì)于上面提到的翻譯,在計(jì)算機(jī)世界里,就是編譯器,只不過(guò)這個(gè)翻譯是有多個(gè),例如本書所說(shuō)的c語(yǔ)言編譯器gcc和匯編語(yǔ)言編譯器nasm,它們能在一起配合,是因?yàn)樗鼈兌级畽C(jī)器語(yǔ)言。舉個(gè)例子,就像小明只會(huì)漢語(yǔ)和英語(yǔ),小紅只會(huì)漢語(yǔ)和法語(yǔ),若他們之間在交流時(shí),小明說(shuō)英語(yǔ),小紅說(shuō)法語(yǔ),他倆相互都聽不懂,所以,當(dāng)說(shuō)英文的小明想跟說(shuō)法語(yǔ)的小紅借作業(yè)時(shí),他必須用漢語(yǔ)告訴小紅。

編譯器知道高級(jí)語(yǔ)言所描述的事物形象是機(jī)器碼,所以各種編譯在高級(jí)語(yǔ)言方面的交流,本質(zhì)上都是將它們都變成統(tǒng)一的機(jī)器碼后實(shí)現(xiàn)的。

吼吼,一不小心又說(shuō)多了,不知道我表達(dá)清楚了沒(méi)有,反正話題就此結(jié)束啦,小弟這里給各位看官準(zhǔn)備了兩個(gè)小文件:C_with_S_c.c和C_with_S_S.S。大家不用細(xì)看,快速瀏覽一下即可,在代碼后面我還有話說(shuō)呢

C_with_S_c.c

1 extern void asm_print(char*,int);2 void c_print(char* str) {3 int len=0;4 while(str[len++]);5 asm_print(str, len);6 }

C_with_S_S.S

1 section .data2 str: db "asm_print says hello world!", 0xa, 03 ;0xa是換行符,0是手工加上的字符串結(jié)束符\0的ascii碼。4 str_len equ $-str56 section .text7 extern c_print8 global _start9 _start:10 ;;;;;;;;;;;; 調(diào)用c代碼中的函數(shù)c_print ;;;;;;;;;;;11 push str ;傳入?yún)?shù)12 call c_print ;調(diào)用c函數(shù)13 add esp,4 ;回收??臻g1415 ;;;;;;;;;;;;;;;;;;; 退出程序 ;;;;;;;;;;;;;;;;;;;;16 mov eax,1 ;第1號(hào)子功能是exit系統(tǒng)調(diào)用17 int 0x80 ;發(fā)起中斷,通知linux完成請(qǐng)求的功能。1819 global asm_print ;相當(dāng)于asm_print(str,size)20 asm_print:21 push ebp ;備份ebp22 mov ebp,esp23 mov eax,4 ;第4號(hào)子功能是write系統(tǒng)調(diào)用24 mov ebx, 1 ;此項(xiàng)固定為文件描述符1,標(biāo)準(zhǔn)輸出(stdout)指向屏幕25 mov ecx, [ebp+8] ;第1個(gè)參數(shù)26 mov edx, [ebp+12] ;第2個(gè)參數(shù)27 int 0x80 ;發(fā)起中斷,通知linux完成請(qǐng)求的功能。28 pop ebp ;恢復(fù)ebp29 ret

代碼C_with_S_c.c中的函數(shù)c_print是被匯編代碼C_with_S_S.S調(diào)用的,在c_print的實(shí)現(xiàn)中,它又調(diào)用匯編代碼中的asm_print。它們的關(guān)系如圖

?

下節(jié)再解釋代碼,先去吃飯了。

接上節(jié),前文請(qǐng)見“一步步編寫操作系統(tǒng) 69 匯編語(yǔ)言和c語(yǔ)言共同協(xié)作”,

本節(jié)是對(duì)前文的代碼說(shuō)明,代碼再貼過(guò)來(lái),C_with_S_c.c如下:

1 extern void asm_print(char*,int);2 void c_print(char* str) {3 int len=0;4 while(str[len++]);5 asm_print(str, len);6 }

代碼C_with_S_c.c的第1行是聲明外部函數(shù)asm_print,通知編譯器這個(gè)函數(shù)并不在當(dāng)前文件中定義。我們知道它定義在文件C_with_S_S.S中,但編譯器是不知道的,所以只能在鏈接階段將此函數(shù)重新定位,編排地址。

第2~6行是c_print的實(shí)現(xiàn),在它的內(nèi)部,它又調(diào)用了匯編代碼C_with_S_S.S中的函數(shù)asm_print,經(jīng)過(guò)第1行的聲明,我們要給它提供兩個(gè)參數(shù):字符串的起始地址及長(zhǎng)度。

特別強(qiáng)調(diào)一下,由于這里并不打算把c標(biāo)準(zhǔn)庫(kù)也鏈接進(jìn)來(lái),所以在求字符串長(zhǎng)度時(shí),我們不能用string.h中的strlen函數(shù)。也就是說(shuō)即使include <string.h>將其strlen的聲明加進(jìn)來(lái),沒(méi)有strlen實(shí)現(xiàn)本身所在的.o文件也是不行的。函數(shù)聲明的作用是:一方面是告訴編譯器該函數(shù)的參數(shù)所需要的??臻g大小及返回值,這樣編譯器能為其準(zhǔn)備好執(zhí)行環(huán)境,另一方面是如果該函數(shù)是在外部文件中定義的,一定要在鏈接階段時(shí)將其對(duì)應(yīng)的目標(biāo)文件一塊鏈接進(jìn)來(lái)。所以這里第3~4行通過(guò)while循環(huán)求字符串的長(zhǎng)度。字符串結(jié)尾必須是空字符’\0’才行,否則while就是死循環(huán)了。這個(gè)字符串是代碼C_with_S_S.S提供的,我們轉(zhuǎn)過(guò)去看看。

1 section .data2 str: db "asm_print says hello world!", 0xa, 03 ;0xa是換行符,0是手工加上的字符串結(jié)束符的ascii碼。4 str_len equ $-str56 section .text7 extern c_print8 global _start9 _start:10 ;;;;;;;;;;;; 調(diào)用c代碼中的函數(shù)c_print ;;;;;;;;;;;11 push str ;傳入?yún)?shù)12 call c_print ;調(diào)用c函數(shù)13 add esp,4 ;回收??臻g1415 ;;;;;;;;;;;;;;;;;;; 退出程序 ;;;;;;;;;;;;;;;;;;;;16 mov eax,1 ;第1號(hào)子功能是exit系統(tǒng)調(diào)用17 int 0x80 ;發(fā)起中斷,通知linux完成請(qǐng)求的功能。1819 global asm_print ;相當(dāng)于asm_print(str,size)20 asm_print:21 push ebp ;備份ebp22 mov ebp,esp23 mov eax,4 ;第4號(hào)子功能是write系統(tǒng)調(diào)用24 mov ebx, 1 ;此項(xiàng)固定為文件描述符1,標(biāo)準(zhǔn)輸出(stdout)指向屏幕25 mov ecx, [ebp+8] ;第1個(gè)參數(shù)26 mov edx, [ebp+12] ;第2個(gè)參數(shù)27 int 0x80 ;發(fā)起中斷,通知linux完成請(qǐng)求的功能。28 pop ebp ;恢復(fù)ebp29 ret

在代碼C_with_S_S.S的第2行,定義待打印的字符串時(shí),在結(jié)尾人為的加了個(gè)0,它就是空字符’\0’的ascii碼。

第8~9行是將_start導(dǎo)出為全局符號(hào),為的是給鏈接器用的,之前解釋過(guò)了。

為了在匯編文件中引用外部的函數(shù)(未必是c代碼中的),需要用extern來(lái)聲明所需要的函數(shù)名。

由于我們用到了外部的函數(shù)c_print,所以在第7行用extern c_print來(lái)聲明c_print函數(shù)是外部的。第11~13行是為外部函數(shù)c_print壓棧傳參,調(diào)用它后清理?xiàng)?臻g。

第16~17行是調(diào)用exit系統(tǒng)調(diào)用告訴linux我要正常退出。

在匯編語(yǔ)言中導(dǎo)出符號(hào)名是用global關(guān)鍵字,這在之前說(shuō)_start時(shí)大伙已有所耳聞,global是將符號(hào)導(dǎo)出為全局屬性,對(duì)程序中的所有文件可見,這樣其它外部文件中也可以引用被global導(dǎo)出的符號(hào)啦,無(wú)論該符號(hào)是函數(shù)還是變量。

由于在c代碼文件C_with_S_c.c中也調(diào)用了這里的asm_print函數(shù),所以為了讓外部代碼可以引用asm_print。我們?cè)诘?9行用global asm_print將其導(dǎo)出。

第20行之后是asm_print的實(shí)現(xiàn),相信大家已經(jīng)非常明白了,不解釋。

好啦,通過(guò)這兩個(gè)例子我相信大伙兒已經(jīng)掌握c和匯編混合編程的方法啦,確切說(shuō)是方法之一。對(duì)于這種匯編代碼和C代碼單獨(dú)編譯的方式還是較容易的,以后咱們會(huì)講C內(nèi)聯(lián)匯編的方式難為難為大家的,玩笑玩笑,只要用心沒(méi)有學(xué)不會(huì)的(聽上去似乎覺(jué)得更難了^_^,沒(méi)事沒(méi)事)。

有關(guān)混合編程的部分就說(shuō)完了,總結(jié)一下:

  • 在匯編代碼中導(dǎo)出符號(hào)供外部引用是用關(guān)鍵字global,引用外部文件的符號(hào)是用關(guān)鍵字extern。
  • 在C代碼中只要將符號(hào)定義為全局便可以被外部引用(一般情況下無(wú)須用額外關(guān)鍵字修飾,具體請(qǐng)參考c語(yǔ)言手冊(cè)),引用外部符號(hào)時(shí)用extern聲明即可。

好了,大爺再來(lái)玩哦。

總結(jié)

以上是生活随笔為你收集整理的一步步编写操作系统 69 汇编语言和c语言共同协作 70的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。