七种寻址方式:
1. 立即数寻址:mov al,34h(B0 34)
a) 通过DS和IP算出物理地址(DS左移4位+IP),从内存中拿到操作码B0
b) 拿到指令队列缓冲器
c) 从指令队列缓冲器中拿到执行部分电路控制,此刻就知道是要向AL中放数据
d) 再通过DS和IP算出物理地址(DS左移4位+IP),从内存中拿到立即数34h
e) 传到指令队列缓冲器
f) 在放到AX的AL中
2. 寄存器寻址:mov ds,ax(8E 08)
a) 逻辑地址在寄存器中
b) 通过DS和IP算出物理地址(DS左移4位+IP),从内存中拿到操作码8E
c) 传到指令队列缓冲器中
d) 从指令队列缓冲器中拿到执行部分电路控制,此刻知道AX中存放着逻辑地址
e) 将AX中的值传递给段寄存器中的内部暂存器
f) 内部暂存器传给DS
3. 存储器寻址
a) 直接寻址方式:mov ax,[2000h](A1 00 20)
i. 通过DS和IP算出物理地址(DS左移4位+IP),从内存中拿到操作码A1
ii. 将操作码A1传到指令队列缓冲器中
iii. 从指令队列缓冲器中拿到执行部分电路控制,此刻知道要使用AX
iv. 在通过地址加法器拿下一个字00,传到指令队列缓冲器中
v. 不够,放入内部暂存器,在从内存中那一个字节20,放入内部暂存器
vi. 通过地址加法器DS(30000)左移4位+IP(2000),从32000的物理地址中拿数据
vii. 将拿到的数据传到队列缓冲器
viii. 将队列缓冲器中的数据放入AX
b) 寄存器间接寻址方式:mov ax,[bx](8B 07)
i. 通过DS和IP算出物理地址(DS左移4位+IP),从内存中拿到操作码8B
ii. 将操作码8B传到指令队列缓冲器中
iii. 从指令队列缓冲器中拿到执行部分电路控制,此刻知道要用AX
iv. 从内存中读取下一个字节07,传到指令队列缓冲器,再传到执行部分
v. BX中的值传到内部暂存器,内部暂存器再传给DS
vi. 在通过地址加法器DS(30000)左移4位+IP(2000),从32000的物理地址中拿数据
vii. 在将数据从内存中读取(2个字节),传给指令队列缓冲器
viii. 再将数据放入AX
c) 寄存器相对寻址方式:mov ax,[SI + 1000](8B 84 00 10)
i. 通过DS和IP算出物理地址(DS左移4位+IP),从内存中拿到操作码8B
ii. 将操作码8B传到指令队列缓冲器中
iii. 从指令队列缓冲器中拿到执行部分电路控制,此刻知道要用AX
iv. 从内存中读取下一个字节84,传到指令队列缓冲器,再传到执行部分
v. 将SI中的值传到ALU等待
vi. 从内存中读取下一个字节00
vii. 放入指令队列缓冲器
viii. 从内存中读取下一个字节10
ix. 放入ALU,和SI相加
x. 将结果传入内部暂存器,再传给IP段寄存器
xi. 在通过地址加法器找到实际物理地址
xii. 从内存中读取数据
xiii. 放入AX
d) 基址变址寻址方式:mov ax,[bx + si](8B 00)
i. 通过DS和IP算出物理地址(DS左移4位+IP),从内存中拿到操作码8B
ii. 将操作码8B传到指令队列缓冲器中
iii. 从指令队列缓冲器中拿到执行部分电路控制
iv. 将BX放入ALU
v. 从内存中读取下一个字节(00)
vi. 放入指令队列缓冲器
vii. 将SI放入ALU,BX和SI相加
viii. 结果传给内部暂存器,再传给IP段寄存器
ix. 在通过地址加法器找到实际物理地址
x. 从内存中读取数据
xi. 放入AX
e) 相对基址变址寻址方式:movax,[bx + si + 1000]
i. 通过DS和IP算出物理地址(DS左移4位+IP),从内存中拿到操作码8B
ii. 将操作码8B传到指令队列缓冲器中
iii. 从指令队列缓冲器中拿到执行部分电路控制
iv. 将BX放入ALU
v. 从内存中读取下一个字节(80)
vi. 放入指令队列缓冲器
vii. 将SI放入ALU,BX和SI相加
viii. 再等待,从内存读取下一个字节
ix. 然后ALU再和读取到的数相加
x. 结果放入内部暂存器,再传给IP
xi. 在通过地址加法器找到实际物理地址
xii. 从内存中读取数据
xiii. 放入AX
寻址方式的效率排序(由高到低):
寄存器寻址 | 访问一次内存,且不做运算 |
寄存器间接寻址 | 访问两次内存,且不做运算 |
立即数寻址 | 访问三次内存,且不做运算 |
基址变址寻址 | 访问三次内存,且做一次加法运算 |
直接寻址 | 访问四次内存,且做一次加法运算 |
寄存器相对寻址 | 访问五次内存,且做一次加法运算 |
相对基址变址寻址 | 访问五次内存,且做两次加法运算 |
在写汇编时,会考虑效率,比如
movax, 0h
xorax, ax
subax, ax
都是将AX置0,但下面两种的效率更高
汇编执行时有一个指令周期,跑一圈下来的时间,就是时间复杂度,可以参考手册