3.2程序編碼
linux->gcc -Og -o p p1.c p2.c
gcc指GCC C編譯器
-Og 告訴編譯器使用生成符合原始C代碼整體結(jié)構(gòu)的機(jī)器代碼優(yōu)化
-o是增加優(yōu)化級(jí)別
linux->gcc -Og -S p1.c
生成p1.s文件,即為p1.c的匯編代碼
linux->gcc -Og -c p1.c
生成p1.c的目標(biāo)代碼文件p1.o,二進(jìn)制格式
他的16進(jìn)制為:53 48 89 d3 e8 00 00 00 00 48 89 03 5b c3
1.C預(yù)處理器擴(kuò)展源代碼,插入所有用#include命令指定的文件,并擴(kuò)展所有用#define聲明指定的宏
2.編譯器產(chǎn)生源文件的匯編代碼p1.s,p2.s
3.匯編器將匯編代碼轉(zhuǎn)化為二進(jìn)制目標(biāo)代碼(機(jī)器代碼的一種,他包含所有指令的二進(jìn)制表示,但還沒有填入全局值的地址)文件p1.o,p2.o
4.鏈接器將目標(biāo)代碼文件與實(shí)現(xiàn)庫函數(shù)(如printf)代碼合并,產(chǎn)生最終的可執(zhí)行代碼文件p(相當(dāng)于會(huì)找調(diào)用的函數(shù)的地址然后通過鏈接器合并)
3.2.1機(jī)器級(jí)代碼
1.程序計(jì)數(shù)器:%rip表示,通常存儲(chǔ)下一條指令在內(nèi)存中的地址
2.整數(shù)寄存器:包含16個(gè)命名的位置,分別存儲(chǔ)64位的值,可以存儲(chǔ)地址或整數(shù)數(shù)據(jù),有的寄存器用來存儲(chǔ)某些重要的程序狀態(tài),其他的用來保存臨時(shí)數(shù)據(jù)如過程參數(shù)和局部變量及函數(shù)的返回值
3.條件碼寄存器保存最近執(zhí)行的算術(shù)或邏輯指令的狀態(tài)信息(比如實(shí)現(xiàn)if和while語句)
4.一組向量寄存器可以存放一個(gè)或多個(gè)整數(shù)或浮點(diǎn)數(shù)
機(jī)器級(jí)代碼的表示
機(jī)器級(jí)代碼只是簡單將內(nèi)存看成一個(gè)很大的,按字節(jié)尋址的數(shù)組
C語言的聚合數(shù)據(jù)類型如數(shù)組和結(jié)構(gòu).在機(jī)器代碼中用一組連續(xù)的字節(jié)表示
對標(biāo)量數(shù)據(jù)類型,匯編代碼不區(qū)分有符號(hào)和無符號(hào)整數(shù),不區(qū)分各種類型的指針,甚至不區(qū)分整數(shù)和指針
程序內(nèi)存
程序的可執(zhí)行機(jī)器代碼 操作系統(tǒng)需要的一些信息 用來管理過程調(diào)用和返回的運(yùn)行時(shí)棧 用戶分配的內(nèi)存塊(用malloc庫函數(shù)分配的)
一條機(jī)器指令只執(zhí)行基本的操作
存放在寄存器的兩個(gè)數(shù)字相加
在存儲(chǔ)器和寄存器之間傳送數(shù)據(jù)
條件分支轉(zhuǎn)移到新的指令地址
3.4.2數(shù)據(jù)傳送指令
movb 傳送字節(jié)
movw 傳送字
movl 傳送雙字 (例外目的為寄存器時(shí),movl會(huì)將寄存器高位4字節(jié)設(shè)置為0)
例如movl $-1,%eax 00000000FFFFFFFF
movq 傳送四字
movabsq 其他只能將32位立即數(shù)傳送到寄存器,而且absq能直接將64位立即數(shù)只能傳送到寄存器
movabsq -1,%al %rax = 00112233445566FF
movw -1,%eax %rax = 00000000FFFFFFFF
movq $-1,%rax %rax = FFFFFFFFFFFFFFFF
剩余字節(jié)填充為0
movzbw 零擴(kuò)展從字節(jié)傳送到字
movzbl 零擴(kuò)展從字傳送到雙字
bwlq排列組合,但是沒有movzlq因?yàn)閙ovl就能替代movzlq
剩余字節(jié)通過符號(hào)擴(kuò)展填充
movsbw 做了符號(hào)擴(kuò)展的字節(jié)傳送到字
movsbl 做了符號(hào)擴(kuò)展的字節(jié)傳送到雙字
ctlq %eax符號(hào)擴(kuò)展到%rax
bwlq排列組合