1. X86cpu工作原理

image-20230611121633671

程序计数器PC存储了下一条要运行的指定的地址,在x86cpu上,PC就是:cs:ip,控制单元读取ip寄存器中的地址后,将此地址送上地址总线,cpu由此得到了要执行的指令,然后将指令存入指令寄存器IR中。下一步指令译码器将此指令解码,解码后得到了操作数和操作码,于是操作控制器OC就给运算单元下令,运算单元就开始执行指令。ip寄存器的值被加上当前指令的大小,由此循环。

IA32的指令格式如下:

image-20230611123557111

2. 实模式的寻址

8086的地址总线是20位宽,意味着寻址范围为:2^20=1MB,但内部寄存器都是16位的,若采用单一寄存器来寻址只能访问:2^16=64KB空间。

为了解决16位寄存器不能寻址20位的问题,因此通过先把16位的段基址左移四位变成20位后,在加上段内偏移地址,这样就形成了20位地址,只要保证了段基址是20位的,偏移地址是多少位就不用关心了。

3.操作系统——CPU的实模式、保护模式和长模式_Strive for the best!的博客-CSDN博客

下面列举一下寻址实例:所有的利用寄存器寻址的方式,每个寄存器都有对应的段基址,寄存器的默认段基址见上一章

  1. 直接寻址(Direct addressing):

    MOV AX, [0x1234]
    mov ax, [fs:0x5678]

    0x1234是段内偏移地址,默认的段地址是DS,这一条指令是将内存地址DS:0x1234处的值写入ax寄存器。

    第二条指定显示指定段基址为fs,因此是将内存地址FS:0x5678处的值写入ax寄存器。

    注意:段基址都需要先左移4位再与段内偏移相加

  2. 基址寻址(Base addressing):

    MOV AX, [BX + 0x10]

    这个例子中,将从BX寄存器所指定的内存地址加上偏移量0x10处读取一个字(16位)的数据,并将其存储在AX寄存器中。bx默认的段寄存器为DS,因此实际的寻址地址为:DS:bx+0x10

3.栈的布局

image-20230611131141910

栈空间也是内存中一段区域,我们程序员可以自由分配,SS栈段寄存器左移4位指向栈底,栈的生长是向低地址方向发展,sp指向了栈顶。

在进行函数调用时,例如使用call指令,需要将PC压栈,然后跳转。