数据的来源:指令中(立即数);CPU内的寄存器(寄存器操作数);内存单元(段地址:偏移地址访问);I/O端口
数据寻址方式:以源操作数为例(指令中的第二个操作数) (1) 立即数寻址:操作数在指令中。例如MOV AX,1234H 或者 MOV AH,12H
(2) 寄存器(直接)寻址:操作数在寄存器中。例如 MOV AX,BX 或者 MOV AH,AL
以上两种寻址方式不需要访问内存单元,以下的寻址方式均需要访问内存单元
访问内存单元的要点,必须给出段地址和偏移地址,然后由CPU内的MMU存储管理单元自动计算出物理地址,再访问。
段地址可以隐含给出,也可以显示给出(段跨越);偏移地址可以多种方式给出(目的是为了支持各种数据结构)。
段地址的给出,如果出现BP寄存器,则隐含在堆栈段SS中,即为SS,否则在数据段DS中。
段地址也可以显式给出,称为段跨越,例如:MOV AX,ES:[BX]。
(3) 直接寻址:直接给出偏移地址。例如 MOV AX,[2000H]。(操作数在:内存单元DS:2000H的地方)
(4) 寄存器间接寻址: 偏移地址在寄存器中。例如:MOV AX,[BX]。(操作数在内存单元DS:BX中)
寄存器只能为BX、BP、SI、DI四个寄存器之一。特别的:MOV AX,[BP]。(操作数在内存单元SS:BP中)
基址寄存器2个:BX、BP。其中BP专门用于访问堆栈段Stack。变址寄存器2个:SI、DI。
(5) 寄存器相对寻址:偏移地址等于寄存器的值加上一个常量。例如:MOV AX,[BX + 2000H]。
注意,此处的寄存器仍然为基址寄存器BX,BP,变址寄存器SI,DI四个寄存器之一。
此种寻址方式一般用来访问一维数组:常量-数组名,寄存器里存放下标(索引Index)。
(6) 基址变址寻址:偏移地址等于基址寄存器的值加上变址寄存器的值。例如MOV AX,[BX + SI]。
注意,有四种组合: MOV AX,[BX + SI] 或MOV AX,[BX + DI] 或MOV AX,[BP + SI] 或MOV AX,[BP + DI]
此种寻址方式一般用来访问一维数组:基址寄存器-数组名,变址寄存器里存放下标(索引Index)。
(7) 基址变址寻址:偏移地址等于基址寄存器的值加上变址寄存器的值再加上一个常量。例如 MOV AX,[BX + SI + 2000H]。
此种寻址方式一般用来访问二维数组:常量-数组名,基址寄存器里存放某一行的首地址,变址寄存器里存放下标(索引 Index)。
指令寻址方式:一条指令执行完毕后,下一条指令在什么地方? (1) 顺序寻址: 一条指令执行完毕,CS:IP 自动指向下一条指令(硬件设计实现的,让IP能够自动+1)。
(2) 跳跃寻址: 中断、循环、跳转、子程序调用时,会由硬件自动装入CS:IP的值。
例如:call near ptr _printf 功能:段内调用printf库函数的代码,段地址CS的值不变,所以不用保存,只保存和恢复IP的值。
例如:call for ptr SCOPY@ 功能:段间调用字符串拷贝函数scopy的代码,段地址和偏移地址均发生变化,所以都需要保存和恢复。
概念:近指针(段内偏移地址) ; 远指针(段地址 + 偏移地址)
CPU中常用的指令:(学习的时候:掌握的十几条指令,了解和会查用其它偶尔出现的没见过的指令) (1) 算术运算指令:add加、adc带进位的加、sub减、sbb带借位的减、inc加1、dec减1、cmp比较(本质做减法根据设置ZF结果是否为0标志为)、mul乘、imul符号乘、div除、idiv符号除、neg取反(由x求-x)。
(2)逻辑运算指令:and逻辑与、or逻辑或、not逻辑取反、xor逻辑异或、test测试(位与)。
(3)移位运算指令: shr逻辑右移、shl逻辑左移、sal算术左移、sar算术右移、rol循环左移、ror循环右移 等。
(4)堆栈操作指令: push进栈、pop出栈。
(5)传送类指令: mov传送、lea装入有效地址(Load Effective Address)、xchg交换。
(6)子程序调用与返回指令: call子程序调用、ret子程序返回。
(7)中断指令: int指令(调用DOS操作系统或BIOS的功能)。
(8)跳转类指令: jmp无条件跳转、jx根据条件x进行跳转(例如jz结果为0则跳转,jnz结果不为0则跳转)、loop循环指令。
(9)输入输出指令: in输入、输出out