Ubuntu下用gcc与nasm联合编译
1.代碼
foo.asm
[plain] view plaincopybar.c
[plain] view plaincopy2.編譯連接+執行(32位)
> ls
bar.c? foo.asm
> nasm -f elf32 -o foo.o foo.asm
> gcc -m32 -c -o bar.obar.c
> ld -m elf_i386 -s -o foobar foo.o bar.o
> ls
bar.c? bar.o? foo.asm? foobar? foo.o
> ./foobar
the 2nd one
3.代碼解釋
extern:EXTERN 偽操作告訴編譯器當前的符號不是在本源文件中定義的,而是在其他源文件中定義的,在本源文件中可能引用該符號。如果本源文件沒有實際引用該符號,該符號將不會被加入到本源文件的符號表中。
global:關鍵字,把符號導出到其他模塊中。global是extern的對立面,如果一個模塊聲明一個extern的符號,然后引用它,為了防止鏈接錯誤,另外某一個模塊必須確實定義了該符號,然后把它聲明為global。
? 1.由于在bar.c中用到函數myprint(),所以要用關鍵字global將其導出
? 2.由于用到本文件外定義的函數choose(),所以要用關鍵字extern聲明
? 3.myprint()和choose()遵循的都是C調用約定,后面的參數先入棧,并由調用者清理堆棧
dd:偽指令——定義雙字。其后的每個操作數占用二個字(低字在前)。 DD還可以把其后的變量或標號的偏移地址和所在段首址存入存儲器內指定 的雙字單元(即DD前面的變量)中,第一個字中存放DD后的變量的偏移地址, 第二個字中存放該變量所在段的段首址。
push:入棧操作,遵守FILO原則(first in last out),而且必須是字操作。
dword:是雙字,也就是32位,可以用來儲存32位整數或者32位內存地址。[拓展:byte是字節,也就是8位,用來儲存char或者char類型指針。word是字,也就是16位。用來儲存16位整數或者16位地址]
add:操作數相加。ADD OPRD1,OPRD2。
? ?1.OPRD1為任一通用寄存器或存儲器操作數,可以是任意一個通用寄存器,而且還可以是任意一個存儲器操作數。
? ?2.OPRD2為立即數,也可以是任意一個通用寄存器操作數.立即數只能用于源操作數。
? ?3.OPRD1和OPRD2均為寄存器是允許的,一個為寄存器而另一個為存儲器也是允許的, 但不允許兩個都是存儲器操作數。
? ?4.加法指令運算的結果對CF、SF、OF、PF、ZF、AF都會有影響.以上標志也稱為結果標志.加法指令適用于無符號數或有符號數的加法運算。
--------------------------------------------------------//32bit或64bit版本
生成的.o文件必須都是32位或者都是64位:
-------------------------------------gcc 命令行參數:
-m32:生成32位代碼
-m64:生成64位代碼
-------------------------------------連接時版本注明:
-m elf_i386 :32位
-m elf_x86_64:
-m elf32_x86_64:
-------------------------------------編譯時版本注明:
-f elf64:64位
-f elf32:32位
---------------------------------------------------------//命令行
-c:只編譯并生成目標文件
./:表示當前目錄的全路徑,一般不在系統環境變量path中的可執行文件 ,運行的時候都要這樣運行,當然寫成絕對路徑也行
總結
以上是生活随笔為你收集整理的Ubuntu下用gcc与nasm联合编译的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用WINHEX合并两个或多个BIN文件
- 下一篇: 操作系统实现(一):从Bootloade