GCC跟NASM联合编译
GCC跟NASM聯合編譯
GCC和NASM聯合編譯GCC和NASM
GCC不用說,C語言的編譯器。NASM是一個x86的匯編器,用來編譯匯編的。最近在研究GCC和NASM聯合編譯,為什么要研究二者的聯合編譯呢?GCC中能嵌套匯編代碼啊?這是因為GCC中嵌套的匯編代碼是AT&T的匯編代碼不是Interl的。其語法格式實在是太復雜了,不是適合初學者(其實是我不會其語法)。下面我們結合一個例子來將二者如何聯合使用。
1.建立示例工程
示例工程很簡單,就下面三個文件:
main.c ---C代碼 hello.asm --- 匯編代碼 Makefile ---編譯命令?其中Makefile的內容如下:
all:nasm -f elf hello.asm -o hello.ogcc -o main main.c hello.o?其中nasm的參數 -f elf表示輸出文件的格式為ELF格式。
2.NASM和C互相調用對方的函數
先看例子的代碼:
extern print_helloworld[section .text] global print_two_hello_world print_two_hello_world: call print_helloworldcall print_helloworld?#include "stdio.h"extern void print_two_hello_world();char *strhello = "Hello,world!\n";void print_helloworld () {printf ("%s",strhello); }int main () {print_two_hello_world();return 0; }? 首先看NASM代碼,先導入一個外部函數print_helloworld(),此函數是C語言定義的一個函數。接下來是定義了一個函數print_two_hello_world,用global關鍵字導出使其可以在C中調用,函數的內容是調用了兩次print_helloword()。
在來看C代碼,代碼很簡單就具體講了,這里主要數一下我們將主函數放在了C代碼中寫,這時因為我們要使用C代碼的函數庫中的printf()函數,如果C代碼中沒有什么庫的依賴可以將主函數放在匯編代碼中,具體的實現請參考《自己動手寫操作系統》一書。
3.NASM和C互相調用對方的變量
同樣先看代碼:
global string extern strhello [section .data] string:db 'I am Chinese.',0x0A,0x0 [section .text]global print_helloglobal cpy_mem print_hello: mov edx, 13mov ecx,[strhello]mov ebx,1mov eax,4int 0x80?#include "stdio.h" #include "string.h" extern char *string; extern void print_hello(); extern cpy_mem (void *dest, int len); char *strhello = "Hello,world!\n"; char *str = NULL; int main () {printf ("%x\n",&string);str = &string;printf ("%s", str);print_hello ();return 0; }?Make后的執行結果如下:
具體的代碼內容就部分析了,這里主要將兩個關鍵的地方。
1.在C語言中定義了一個strhello的字符串變量,在C語言中strhello表示的是字符串的首地址,比如字符串的地址是0xa00001,而strhello是個指針即4字節其地址為0xb00001,在C語言中strhello表示的值是0xa00001字符串的首地址,但到了NASM中則表示的strhello變量的首地址了0xb00001,所以
mov ecx,[strhello]?代碼中加了中括號表示是內容,這一點一定要注意,否則會出錯!!
2.第二點要注意的是,在NASM中定義了一個字符串string,在C語言中導入的話,就是表示字符串的首地址,因此要引用該字符串一定要取其地址,不要直接轉為(char*)類型直接用,否則出錯,這是因為直接轉的話,就將字符串的前4個字節轉成了字符串指針,但該指針是不確定會出現段錯誤!
總結
以上是生活随笔為你收集整理的GCC跟NASM联合编译的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++写的一个简单的词法分析器(分析C语
- 下一篇: 用WINHEX合并两个或多个BIN文件