2016
http://mooc.study.163.com/course/USTC-1000029000#/info
2015
http://mooc.study.163.com/course/USTC-1000072000#/info
實(shí)驗(yàn)樓,有實(shí)驗(yàn)環(huán)境
https://www.shiyanlou.com/courses/195
參考資料 深入理解Linux內(nèi)核第三版
1. 存儲(chǔ)程序計(jì)算機(jī)工作模型
這個(gè)小節(jié),理解兩個(gè)問(wèn)題
0x01 什么是馮諾依曼體系結(jié)構(gòu)?
馮諾依曼體系結(jié)構(gòu)就是存儲(chǔ)程序計(jì)算機(jī),從如下兩個(gè)方面來(lái)看:
硬件方面,計(jì)算機(jī)可以抽象成由CPU,內(nèi)存組成,CPU和內(nèi)存之間通過(guò)總線連接,
CPU內(nèi)部有寄存器,如IP(Instruction Pointer)
16位的CPU叫IP
32位的CPU叫EIP
64位的CPU叫RIP
通常叫做IP,IP始終指向要執(zhí)行的代碼CS(Code Segment)
從程序員角度來(lái)看,
Memory holds instructions and data
CPU interpreter of instructions
0x02 CPU識(shí)別什么樣的指令
API:程序員與計(jì)算機(jī)的接口界面(Application Program Interface)
ABI:程序與CPU的接口界面(Application Binary Interface)
2. 32位X86匯編基礎(chǔ)
這個(gè)小節(jié),理解幾種寄存器,幾種尋址方式
0x01 通用寄存器
寄存器 | 描述 |
---|---|
AX,EAX | 累加器(Accumulator) |
BX,EBX | 基地址寄存器(Base Register) |
CX,ECX | 計(jì)數(shù)寄存器(Count Register) |
DX,EDX | 數(shù)據(jù)寄存器(Data Register) |
EBP | 堆椓赀矗基指針(Base Pointer) |
ESI | 變址寄存器(Index Register) |
EDI | 變址寄存器(Index Register) |
ESP | 堆棧頂指針(Stack Pointer) |
0x02 段寄存器
寄存器 | 描述 |
---|---|
CS | 代碼段寄存器(Code Segment Register) |
DS | 數(shù)據(jù)段寄存器(Data Segment Register) |
ES | 附加段寄存器(Extra Segment Register) |
SS | 堆棧段寄存器(Stack Segment Register) |
FS | 附加段寄存器(Extra Segment Register) |
GS | 附加段寄存器(Extra Segment Register) |
0x03 幾種尋址方式
movl %eax, %edx // edx = eax; 寄存器尋址(register mode)
movl $0x123, %edx // edx = 0x123; 立即數(shù)(immediate)
movl 0x123, %edx // edx = *(int32_t*)0x123; 直接尋址(direct)
movl (%ebx), %edx // edx = *(int32_t*)ebx; 間接尋址(indirect)
movl 4(%ebx), %edx // edx = *(int32_t*)(ebx+4); 基址尋址(displaced)
3. 反匯編一個(gè)簡(jiǎn)單的C程序
這是一個(gè)實(shí)驗(yàn),實(shí)驗(yàn)樓有提供環(huán)境
https://www.shiyanlou.com/courses/195/labs/555/document
反匯編一段代碼,然后分析其匯編代碼
0x01 編譯下面這段代碼
int g(int x)
{
return x + 3;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8) + 1;
}
將這段代碼保存成main.c,用如下命令來(lái)進(jìn)行編譯
gcc –S –o main.s main.c -m32
命令執(zhí)行完后,生成main.s這個(gè)匯編文件
gcc --help
-S Only run preprocess and compilation steps
-o <file> Write output to <file>
-m32 以32位CPU編譯
0x02 分析匯編代碼
# 分析前先了解如下幾個(gè)指令的等價(jià)指令
pushl %eax
subl $4, %esp
movl %eax, (%esp)
popl %eax
movl (%esp), %eax
addl $4, %esp
call 0x12345
pushl %eip(*)
movl $0x12345, %eip(*)
ret
popl %eip(*)
enter
pushl %ebp
movl %esp, %ebp
leave
movl %ebp, %esp
popl %ebp
# 用(*)標(biāo)注的寄存器,說(shuō)明該寄存器不能被程序員直接修改,必須通過(guò)特定的指令間接修改
下圖是main.s
下面是對(duì)這段代碼的堆棧的分析
小結(jié)(三個(gè)法寶)
存儲(chǔ)程序計(jì)算機(jī)工作模型狞尔,計(jì)算機(jī)系統(tǒng)最最基礎(chǔ)性的邏輯結(jié)構(gòu);
函數(shù)調(diào)用堆棧巩掺,高級(jí)語(yǔ)言得以運(yùn)行的基礎(chǔ)沪么,只有機(jī)器語(yǔ)言和匯編語(yǔ)言的時(shí)候堆棧機(jī)制對(duì)于計(jì)算機(jī)來(lái)說(shuō)并不那么重要,但有了高級(jí)語(yǔ)言及函數(shù)锌半,堆棧成為了計(jì)算機(jī)的基礎(chǔ)功能禽车;
enter
- pushl %ebp
- movl %esp,%ebp
leave
- movl %ebp,%esp
- popl %ebp
函數(shù)參數(shù)傳遞機(jī)制和局部變量存儲(chǔ)
中斷,多道程序操作系統(tǒng)的基點(diǎn)刊殉,沒有中斷機(jī)制程序只能從頭一直運(yùn)行結(jié)束才有可能開始運(yùn)行其他程序殉摔。