2.05k likes | 2.22k Views
第三章 80X86 的指令系统和寻址方式. 指令系统 :一台计算机的所有指令的集合 计算机中指令从组成看 分为两部分: 操作码字段 和 操作数字段 ① 操作码字段 用来表示计算机所要完成的操作。 ② 操作数字段 用来指出指令执行操作的过程中所需操作数。 包括 操作数的来源 和 操作结果的去向 。. 指令的格式一般是: 操作数字段可以有一个、二个或三个,通常称为一地址、二地址或三地址指令。近代多数机器则使用二地址指令,此时分别称两个操作数为源操作数和目的操作数。也可以表示为: 操作码 [ 目的操作数 [ , 源操作数 ]]
E N D
第三章 80X86的指令系统和寻址方式 指令系统:一台计算机的所有指令的集合 计算机中指令从组成看 分为两部分:操作码字段和操作数字段 ①操作码字段用来表示计算机所要完成的操作。 ②操作数字段用来指出指令执行操作的过程中所需操作数。 包括操作数的来源和操作结果的去向。
指令的格式一般是: • 操作数字段可以有一个、二个或三个,通常称为一地址、二地址或三地址指令。近代多数机器则使用二地址指令,此时分别称两个操作数为源操作数和目的操作数。也可以表示为: 操作码[目的操作数[,源操作数]] 按操作数字段的不同在IBM PC机中指令有三种格式: ①操作码 ②操作码 操作数 ③操作码 目的操作数 ,源操作数
3.1 80X86的寻址方式 • 汇编指令中操作码、操作数的表示: 用助记符来表示操作码,用符号或符号地址来表示操作数或操作数地址。 • 汇编指令与机器指令是一一对应的。 • 操作数类型:四种 ①寄存器操作数 ②立即数操作数 ③存储器操作数 ④I/O端口操作数
寻址方式的含义 寻址方式的含义:指寻找指令中操作数的方式。 1、提供指令的地区:代码段。 2、提供操作数的地区 ⑴存储器代码段 ⑵存储器数据段 ⑶存储器堆栈段 ⑷存储器附加段 ⑸CPU内部的寄存器 ⑹I/O端口
8086的寻址方式 与数据有关的寻址方式:以 MOV d,s指令为例,这是传送指令,第1操作数为目的操作数d,第2操作数为源操作数s,指令执行的结果应把s送到d。 • 立即寻址 MOV AX , 3069H • 寄存器寻址 MOV AL , BH • 直接寻址 MOV AX , [ 2000H ] • 寄存器间接寻址 MOV AX , [ BX ] • 寄存器相对寻址 MOV AX , COUNT [ SI ] • 基址变址寻址 MOV AX , [ BP ] [ DI ] • 相对基址变址寻址 MOV AX , MASK [ BX ] [ SI ] 存储器寻址
3.1.1与数据有关的寻址方式 • 1 立即寻址方式(Immediate Addressing): 指令所需的操作数直接在指令代码中,立即数可以是8位或16位。对于386及其后继机型则可以是8位或32位。 立即数的书写:立即数是常数可以直接书写。 用法:立即寻址方式用来表示常数,它经常用于给寄存器赋初值,并且只能用于源操作数字段,不能用于目的操作数字段,且源操作数长度应与目的操作数长度一致。 例3.1 MOV AL,5 指令执行后,(AX)=05H 例3.2 MOV AX,3064H 指令执行后,(AX)=3064H 例3.3 MOV EAX,12345678H 指令执行后,(EAX)=12345678H
2.寄存器寻址方式(Register Addressing): 指令所需的操作数在CPU内部的通用寄存器或段寄存器中。指令中直接给出寄存器地址。 对于16位操作数,寄存器可以是AX、BX、CX、DX、SI、DI、SP和BP等;对于8位操作数,寄存器可以是AL、AH、BL、BH、CL、CH、DL和DH。 例3.4(a) MOV AX,BX 如指令执行前(AX)=3064H,(BX)=1234H; 则指令执行后, (AX)=1234H,(BX)保持不变。 例3.4(b) MOV ECX,EDX 如执行前(ECX)=01237541H, (EDX)=12345678H; 则指令执行后,(ECX)=12345678H,(EDX)保持不变。 除上述两种寻址方式外,以下各种寻址方式的操作数都在除代码段以外的存储区中,通过采用不同方式求得操作数地址,从而取得操作数。
存储器寻址 1.指令所需的操作数在存储器中。 2.存储器寻址中的段基值的来源:由某个段寄存器提供。 3.偏移量(有效地址EA): 指存放操作数的存储单元与段起始单元地址之间的字节距离。下述各种寻址方式即为求得有效地址(EA)的不同途径。 4.有效地址由以下四种成分组成: ①位移量(displacement):是存放在指令中的一个8位、16位或32位的数,但它不是立即数,而是一个地址。 ②基地址(index):是存放在基址寄存器中的内容。它是有效地址中的基址部分,通常用来指向数据段中数组或字符串的首地址。 ③变地址(index):是存放在变址寄存器中的内容。它通常用来访问数组中的某个元素或字符串中的某个字符。
比例因子(scale factor):是386及其后继机型新增加的寻址方式中的一个术语,其值可为1,2,4或8。在寻址中,可用变址寄存器的内容乘以比例因子来取得变址值。这类寻址方式对访问元素长度为2,4,8字节的数组特别有用。 有效地址的计算可以用下式表示: EA=基址+(变址*比例因子)+位移量 说明:这四个成分中,除比例因子是固定值外,其他三个成分都可正可负,以保证指针移动的灵活性。 5.四种存储器操作数寻址方式: ①直接寻址方式: ②寄存器间接寻址方式: ③变址寻址和基址寻址方式: ④基址变址寻址方式:
表3.1 16/32位寻址时有效地址四种成分的组成 • 8086/80286只能使用16位寻址,而80386及其后继机型则既可用32位寻址,也可用16位寻址。其规定见表3.1 表3.2 默认段选择规则
3直接寻址方式 ①直接寻址方式(Direct Addressing): 操作数存放在主存的存储单元中,其有效地址EA由指令代码中的位移量提供。所以必须先求出操作数的物理地址,然后再访问存储器才能取得操作数。 如操作数在数据段中,则物理地址=16d (DS)+EA。同时还允许数据存放在数据段以外的其他段中,此时应在指令中指定段跨越前缀,在计算物理地址时应使用指定的段寄存器。 有两种表示方式: 1) 用数值地址表示 2) 用符号地址表示
例3.5 MOV AX,[2000H] 如(DS)=3000H,则执行结果为(AX)=3050H 还可以用符号地址代替数值地址。执行情况如图3.3 如: MOV AX,VALUE 此时VALUE为存放操作数单元的符号地址。如写成: MOV AX,[VALUE]是等价的。 如VALUE在附加段中,则应指定段跨越前缀如下: (ES为段寄存器) MOV AX,ES: VALUE 或 MOV AX,ES: [VALUE]
例3.6 MOV EAX,DATA 指令中的DATA为符号地址,其中存放着32位操作数,故目的操作数也应使用32位寄存器。 直接寻址方式适用于处理单个变量,例如要处理某个存放在存储器里的变量,可用直接寻址方式把该变量先取到一个寄存器中,然后再作进一步处理。 例:MOV BX,DS:[1000H] 比较:MOV BX,ES:[1000H] 例:MOV BX,VAR 等价于 MOV BX,DS:VAR 例:MOV DA_BYTE,0FH 等价于 MOV DS:DA_BYTE,0FH 例:MOV CL,DA+3 等价于 MOV CL,DS:DA+3 区别1:MOV CL,ES:DA+3 区别2:MOV CX,DA+3
主存 00000H … DS 数据段起始单元地址 偏移量1000H BX 字传送 34H 1234H 12H … FFFFFH 直接寻址示意图 • 例Ⅰ:MOV BX,DS:[1000H]
直接寻址示意图 主存 • 例Ⅱ:MOV BX,ES:[1000H] 00000H … ES 附加段起始单元地址 偏移量1000H BX 字传送 FFH 00FFH 00H … FFFFFH
直接寻址示意图 主存 • 例Ⅲ: MOV BX,VAR 00000H … DS 数据段起始单元地址 偏移量 BX 字传送 VAR 34H 1234H 12H … FFFFFH
直接寻址示意图 主存 • 例Ⅳ:MOV DA_BYTE,0FH 00000H … DS 数据段起始单元地址 偏移量 立即数 字节传送 0FH DA_BYTE 0FH … FFFFFH
直接寻址示意图 主存 • 例Ⅴ:MOV CL,DA+3 00000H … DS 数据段起始单元地址 位移量 DA CL 字节传送 0FH 0FH DA+3 … FFFFFH
直接寻址示意图 主存 • 区别1:MOV CL,ES:DA+3 00000H … ES 附加段起始单元地址 位移量 DA CL 字节传送 2FH 2FH DA+3 … FFFFFH
直接寻址示意图 主存 • 区别2:MOV CX,DA+3 00000H … DS 数据段起始单元地址 位移量 DA CX DA+3 0FH 字传送 120FH 12H … FFFFFH
3.1.1.4寄存器间接寻址方式 • 寄存器间接寻址方式( Register Indirect Addressing) 指令所需的操作数在存储单元中,操作数的有效地址EA在基址寄存器BX、BP或变址寄存器SI、DI中。 如果指令中指定的寄存器是BX、SI、DI,则操作数在数据段中,所以用DS寄存器的内容作为段地址,即操作数的物理地址为:物理地址=16d*(DS)+(BX) 或 物理地址=16d*(DS)+(SI) 或 物理地址=16d*(DS)+(DI)
主存 00000H … 数据段起始单元地址 20000H DS 偏移量=(BX) =1000H AX 字节传送 A0H A0H 21000H 50H 50H … FFFFFH • 例 3.7 MOV AX,[BX] 如果 (DS)=2000H, (BX)=1000H, 则 物理地址=20000+1000=21000H 执行结果为: (AX)=50A0H • 指令中也可指定段跨越前缀来取得其他段中的数据。如: MOV AX, ES:[BX]
例3.8 MOV ECX,[EDX] 指令把数据段中有效地址存放在EDX寄存器中的32位操作数传送到ECX寄存器中。 • 这种寻址方式可以用于表格处理,执行完一条指令后,只需修改寄存器内容就可取出表格中的下一项。 • 例: MOV CH,[SI] 等价于 MOV CH,DS:[SI] MOV CX,[BP] 等价于 MOV CX,SS:[BP] 根据表3.2的规定,凡使用BP,ESP和EBP时,其默认段为SS段
寄存器间接寻址示意图 主存 • 例Ⅰ:MOV CH,[SI] 00000H … DS 数据段起始单元地址 偏移量=(SI) CH 字节传送 0FH 0FH … FFFFFH
寄存器间接寻址示意图 主存 • 例Ⅱ: MOV CX,[BP] 00000H … SS 堆栈段起始单元地址 偏移量=(BP) CX 字传送 11H 0AF11H AFH … FFFFFH
3.1.1.5寄存器相对寻址方式 • 寄存器相对寻址方式(register relative addressing) • 操作数的有效地址是一个基址或变址寄存器的内容和指令中指定的8位或16位位移量之和。即 • 同样,除有段跨越前缀外,对于寄存器为BX、SI、DI的情况,段寄存器用DS,如是BP,则使用SS段寄存器。其物理地址是: • 物理地址=16d*(DS)+(BX/SI/DI)+8/16位位移量 • 或 物理地址= 16d*(SS)+(BP)+8/16位位移量
例3.9 MOV AX, COUNT[SI] (也可以表示为MOV AX,[COUNT+SI]) 其中COUNT为16位位移量的符号地址。 如果(DS)=3000H , (SI)=2000H, COUNT=3000H 则物理地址=30000+2000+3000=35000H 由于地址为(35000H)=1234H,所以(AX)=1234H • 这种寻址方式同样可用于表格处理,表格的首地址可设置为COUNT,利用修改基址或变址寄存器的内容来取得表格中的值。 • 直接变址寻址方式也可以使用段跨越前缀。 • 例如:MOV DL, ES:STRING[SI] • 例: MOV AX,10H[SI] MOV TABLE[DI],12H MOV TAB1[BP],CL
寄存器相对寻址示意图 主存 • 例Ⅰ: MOV AX,10H[SI] 00000H … DS 数据段起始单元地址 EA=(SI)+10H AX 11H 字传送 0AF11H AFH … FFFFFH
寄存器相对寻址示意图 主存 • 例Ⅱ: MOV TABLE[DI],12H 00000H … DS 数据段起始单元地址 EA=TABLE+(DI) TABLE (DI) 立即数 字节传送 12H 12H … FFFFFH
寄存器相对寻址示意图 主存 • 例Ⅲ: MOV TAB1[BP],CL 00000H … SS 堆栈段起始单元地址 EA=TAB1+(BP) TAB1 BP CL 字节传送 62H 62H … FFFFFH
寄存器相对寻址方式在数组访问应用举例 寄存器相对寻址方式常用来访问连续存放在主存中的一维数组、表格、字符串等。 例:一维数组ARY存放在主存的数据段中,数组的每个元素长度相同且占一个字节单元。 指令:MOV AH,ARY[SI] 例:一维数组ARY存放在主存的数据段中,数组的每个元素长度相同且占两个字节单元。 指令:MOV AX,ARY[SI]
寄存器相对寻址方式在一维数组访问应用举例 主存 例:一维数组ARY存放在主存的数据段中,数组的每个元素长度相同且占一个字节单元。指令:MOV AH,ARY[SI] 00000H … DS 数据段起始单元地址 … ARY ARY[0] SI ARY[1] 3H ARY[2] 字节传送 AH ARY[3] EA=ARY+(SI) … FFFFFH
寄存器相对寻址方式在一维数组访问应用举例 主存 例:一维数组ARY存放在主存的数据段中,数组的每个元素长度相同且占两个字节单元。指令:MOV AX,ARY[SI] 00000H … DS 数据段起始单元地址 … ARY ARY[0] ARY[0] SI 4H ARY[0] ARY[1] 字传送 EA=ARY+(SI) AX ARY[0] ARY[2] … FFFFFH
3.1.1.6基址变址寻址方式 • 基址变址寻址( Based Indexed Addressing) • 操作数在存储单元中,其有效地址EA是两个地址分量之和:基址寄存器(BX或BP),变址寄存器(SI或DI)。 • 如果寻址所用基址寄存器是BX,则隐含使用段寄存器DS;如是BP,则隐含使用段寄存器SS。 • 其物理地址为: 物理地址=16d*(DS)+(BX)+(SI/DI) 或 物理地址=16d*(SS)+(BP)+(SI/DI)
例3.10 MOV AX,[BX][DI] (或写为:MOV AX,[BX+DI]) 如(DS)=2100H, (BX)=0158H, (DI)=10A5H 则EA=0158+10A5=11FDH 物理地址=21000+11FD=221FDH 由于(221FDH)=1234H,所以(AX)=1234H。 • 类似地,对于32位寻址方式可有: MOV EDX,[EBX][ESI] • 这种寻址方式同样适用于数组或表格处理,首地址可存放在基址寄存器中,而用变址寄存器来访问数组中的各个元素。由于两个寄存器都可以修改,所以它比直接变址方式更加灵活。 • 此种寻址方式使用段跨越前缀时的格式为: MOV AX,ES:[BX][SI]
3.1.1.7相对基址变址寻址方式 • 相对基址变址寻址(Relative Based Indexed Addressing) • 操作数在存储单元中,其有效地址EA是三个地址分量之和:基址寄存器(BX或BP),变址寄存器(SI或DI)与指令中给出的偏移量三个地址分量之和。 • 如果寻址所用基址寄存器是BX,则隐含使用段寄存器DS;如是BP,则隐含使用段寄存器SS。 • 其物理地址为: 物理地址=16d*(DS)+(BX)+(SI/DI)+8/16位位移量 或物理地址=16d*(SS)+(BP)+(SI/DI)+8/16位位移量
例3.11 MOV AX,MASK[BX][SI](也可以写成MOV AX,MASK[BX+SI]或MOV AX,[MASK+BX+SI])。 如(DS)=3000H,(BX)=2000H,(SI)=1000H,MASK=0250H,则物理地址=16d*(DS)+(BX)+(SI)+MASK =30000+2000+1000+0250 =33250H 由于(33250H)=1234H,所以(AX)=1234H。 • 类似地,对于32位寻址方式可有: MOV EAX,ARRAY[EBX][ECX] • 这种寻址方式为堆栈处理提供了方便。一般(BP)可指向栈顶,从栈顶到数组的首地址可用位移量表示,变址寄存器可用来访问数组中的某个元素。 例Ⅰ. MOV AX,200H[BX][SI] 例Ⅱ. MOV TABLE[BX][DI],0FFH 例Ⅲ. MOV AX,ARRAY[BP][SI] 例Ⅴ. MOV TAB1[BP][DI],DL
相对基址变址寻址示意图 主存 • 例ⅠMOV AX,200H[BX][SI] 00000H … DS 数据段起始单元地址 EA=(BX)+(SI)+200H AX 11H 字传送 0AF11H AFH … FFFFFH
相对基址变址寻址示意图 主存 • 例Ⅱ: MOV TABLE[BX][DI],0FFH 00000H … DS 数据段起始单元地址 EA=TABLE+ (BX)+(DI) TABLE (BX)+(DI) 立即数 字节传送 FFH FFH … FFFFFH
相对基址变址寻址示意图 主存 • 例Ⅲ. : MOV AX,ARRAY[BP][SI] 00000H … SS 数据段起始单元地址 EA=ARRAY+(BP)+(SI) ARRAY (BP)+(SI) AX 11H 字传送 0AF11H AFH … FFFFFH
相对基址变址寻址示意图 主存 • 例Ⅴ.MOV TAB1[BP][DI],DL 00000H … SS 堆栈段起始单元地址 EA=TAB1+(BP)+(DI) TAB1 (BP)+(DI) DL 字节传送 62H 62H … FFFFFH
相对基址变址寻址在访问二维数组中的应用 由于相对基址变址寻址寻址方式中有两个地址分量可以在程序执行过程中进行修改,因此常用来访问存放在主存中的二维数组。例:ARRAY是一个10行、10列的二维数组,按行存放在主存堆栈段中。从数组的首地址ARRAY起依次存放各个元素:第0行元素为ARRAY(0,0)—ARRAY(0,9)共10个,第1行元素为 ARRAY(1,0)—ARRAY(1,9)共10个,…….每个元素占用一个字节单元。 访问数组中某个元素ARRAY(i,j): MOV AL,ARRAY[BP][SI] 例:ARRAY是一个m行、n列的二维数组,按行存放在主存堆栈段中。每个元素占用一个字单元。 访问数组中某个的元素ARRAY(i,j): MOV AL,ARRAY[BP][SI]
存储器操作数寻址方式地址计算小结 BX SI SI OR OR OR BP DI DI OR + + 位移量 BX EU 直接寻址 OR (相对)基址变址寻址 BP 寄存器相对寻址 EA 寄存器间接寻址 CS 0000 BIU OR DS 0000 + 20位物理地址 OR SS 0000 OR ES 0000
80x86新增的寻址方式 • 8.比例变址寻址方式(scaled indexed addressing) • 操作数的有效地址EA=(变址寄存器) 比例因子 + 位移量 • 这种寻址方式与相对寄存器寻址方式相比,增加了比例因子,其优点在于:对于元素大小为2,4,8字节的数组,可以在变址寄存器中给出数组元素下标,而由寻址方式控制直接用比例因子把下标转换为变址值。 • 例3.12:MOV EAX, COUNT [ ESI 4 ] 功能:要求把双字数组 COUNT中的元素3送到EAX 中,用这种寻址方式可 直接在ESI中放入3,选 择比例因子4(数组元 素为4字节长)就可以方 便地达到目的,而不必 像在相对寄存器寻址方 式中要把变址值直接装 入寄存器中。
9.基址比例变址寻址方式(based scaled indexed addressing) • 操作数的有效地址是变址寄存器的内容乘以比例因子再加上基址寄存器的内容之和。 EA= (基址寄存器) + (变址寄存器) 比例因子 • 这种寻址方式与基址变址寻址方式相比,增加了比例因子。 • 例3.13 MOV ECX,[EAX][EDX*8] • 10.相对基址比例变址寻址方式(relative based scaled indexed addressing) EA= (基址寄存器) + (变址寄存器) 比例因子 + 位移量 • 这种寻址方式比相对基址变址方式增加了比例因子,便于对元素为2,4,8字节的二维数组的处理。 • 例3.14 MOV EAX,TABLE[EBP][EDI*4]
3.1.2与转移地址有关的寻址方式 • 这种寻址方式用来确定转移指令及CALL指令的转向地址。 • 3.1.2.1段内直接寻址(intrasegment direct addressing) • 有效地址:当前IP寄存器的内容和指令中指定的8位或16位位移量之和。这种方式的转向有效地址用相对于当前IP值的位移量来表示,所以它是一种相对寻址方式。指令中的位移量是转向的有效地址与当前IP值之差,所以当这一程序段在内存的不同区域运行时,这种寻址方式的转移指令本身不会发生变化。这符合程序再定位的要求。 • 这种寻址方式适用于条件转移及无条件转移指令,用于条件转移指令时,位移量只允许8位。无条件转移指令在位移量为8位时称为短跳转。 • 指令的汇编语言格式表示为: JMP NEAR PTR PROGIA JMP SHORT QUEST • 其中,PROGIA和QUEST均为转向的符号地址,在机器指令中用位移量来表示。在汇编指令中,如果位移量为16位,则在符号地址前加操作符NEAR PTR,如果位移量为8位,则在符号地址前加操作符SHORT。
3.1.2.2段内间接寻址(intrasegment indirect addressing) • 转向有效地址是一个寄存器或是一个存储单元的内容。这个寄存器或存储单元的内容可以用数据寻址方式中除立即数以外的任何一种寻址方式取得,所得到的转向的有效地址用来取代IP寄存器的内容。 • 不能用于条件转移指令,条件转移指令只能使用段内直接寻址的8位位移量,而JMP和CALL指令则可用四种寻址方式中的任何一种。 • 段内间接寻址转移指令的汇编格式可以表示为: JMP BX 或JMP WORD PTR[BP+TABLE] 其中WORD PTR为操作符,用以指出其后的寻址方式所取得的转向地址是一个字的有效地址,也就是说它是一种段内转移。 • 以上两种寻址方式均为段内转移,所以直接把求得的转移的有效地址送到IP寄存器就可以了。其转移的物理地址的计算公式是: 物理地址=16d*(CS)+EA 其中EA即为上述转移的有效地址。
举例:转移的有效地址的计算方法 • 假设: (DS)=2000H, (BX)=1256H, (SI)=528FH, 位移量=20A1H, (232F7H)=3280H, (264E5H)=2450H • 例 3.15 JMP BX 执行该指令后(IP)=1256H • 例3.16 JMP TABLE[BX] 执行该指令后(IP)=(16d*(DS)+(BX)+位移量) =(20000+1256+20A1) =(232F7) =3280H • 例3.17 JMP [BX][SI] 执行该指令后(IP)=(16d*(DS)+(BX)+(SI)) =(20000+1256+528F) =(264E5) =2450H
3.1.2.3段间直接寻址 • 指令中直接提供了转向段地址和偏移地址,所以只要用指令中指定的偏移地址取代IP寄存器的内容,用指令中指定的段地址取代CS寄存器的内容就完成了从一个段到另一个段的转移操作。 • 指令的汇编语言格式可表示为: JMP FAR PTR NEXTROUTINT • 其中, NEXTROUTINT为转向的符号地址, FAR PTR 则是表示段间转移的操作符。
3.1.2.4段间间接寻址 • 用存储器中的二个相继字的内容来取代IP和CS寄存器中的原始内容以达到段间转移的目的。这里存储单元的地址是由指令指定除立即数方式和寄存器方式以外的任何一种数据寻址方式取得。 • 这种指令的汇编语言格式可表示为: JMP DWORD PTR[INTERS+BX] • 其中,[INTERS+BX]说明数据寻址方式为直接变址寻址方式,DWORD PTR为双字操作符,说明转向地址需取双字为段间转移指令。