160 likes | 342 Views
5.7 发挥 80386 及其后继机型的优势. 5.7.1 充分利用高档机的 32 位字长特性 80x86 系列从 80386 起就把机器字长从 16 位增加到 32 位。字长的增加除有利于提高运算精度外,也能提高编程效率。例如,在第 4 章 4.4.3 小节中,例 4.1 所讨论的多字节 ( 如双字长 ) 数的加法,在 8086 中必须用 ADD 或 ADC 指令序列来完成;而在 386 及其后继机型中只用一条 ADD 指令就可完成双字长加法操作。因此,不论在空间方面还是时间方面都有利于程序效率的提高。为了更进一步说明问题,下面举一个例子。.
E N D
5.7 发挥80386及其后继机型的优势 5.7.1 充分利用高档机的32位字长特性 80x86系列从80386起就把机器字长从16位增加到32位。字长的增加除有利于提高运算精度外,也能提高编程效率。例如,在第4章4.4.3小节中,例4.1所讨论的多字节(如双字长)数的加法,在8086中必须用ADD或ADC指令序列来完成;而在386及其后继机型中只用一条ADD指令就可完成双字长加法操作。因此,不论在空间方面还是时间方面都有利于程序效率的提高。为了更进一步说明问题,下面举一个例子。
例5.20 如有两个4字长(64位)数分别存放在datal和data2中,请 用8086指令编写一程序求出它们的和,并把结果存放于data3中。 为了得到4字长数的和,在8086中需要分4段计算,每段一个字长(16位),用4次循环可得到4字长数的和。考虑到每次求和可能有进位值,要用ADC(而不是ADD)指令求和,而且在进入循环前应先清除CF位。 在循环中修改地址指针时用INC指令而不用ADD指令,以免影响求和时得到的进位值(INC指令不影响CF位)。程序如下:
DATA SEGMENT data1 DQ 123456789ABCDEFH data2 DQ 0FEDCBA987654321H data3 DQ ? DATA ENDS CODE SEGMENT START:MOV AX,DATA MOV DS,AX CLC LEA SI,data1 ;data1偏移地址送SI LEA DI,data2 ;data2偏移地址送DI LEA BX,data3 ;data3偏移地址送BX MOV CX,4
BACK:MOV AX,WORD PTR [SI] ;第一个加数送 AX • ADC AX,WORD PTR [DI] ;和第二个加数相加,并送到AX • MOV WORD PTR [BX],AX ;存和值 • INC SI • INC SI • INC DI • INC DI • INC BX • INC BX • LOOP BACK • MOV AX, 4C00H ;返回 DOS • INT 21H • CODE ENDS • END START
例5.21编制80386及其后继机型的程序,实现例5.19的要求。例5.21编制80386及其后继机型的程序,实现例5.19的要求。 在386及其后继机型中可以充分利用其32位字长的特点,每次可对双字求和,这样循环2次就可得到4字长数之和,程序如下。由于循环次数的减少,速度上要优于例5.19的程序。 .386 DATA SEGMENT data1 DQ 123456789ABCDEFH data2 DQ 0FEDCBA987654321H data3 DQ ? DATA ENDS
CODE SEGMENT START: MOV AX,DATA MOV DS,AX CLC LEA SI,data1 ;data1偏移地址送SI LEA DI,data2 ;data2偏移地址送DI LEA BX,data3 ;data3偏移地址送BX MOV CX,2 ;设置循环次数CX=2 BACK:MOV EAX,DWORD PTR [SI] ;第一个加数送 EAX ADC EAX,DWORD PTR [DI] ;和第二个加数相加, ;并送到 EAX MOV DWORD PTR [BX],EAX ;存和值
PUSHF ;保存CF • ADD SI,4 • ADD DI,4 • ADD BX,4 • POPF ;恢复 CF • LOOP BACK • MOV AX,4C00H ;返回 DOS • INT 21H • CODE ENDS • END START
分析以上两例程序实现所需要的时钟周期数,可以得出这样的结论:用386或486运行上述程序,用32位字长计算可获得比用16位字长计算快5~7倍的效果。可见,尽可能利用高档机的32位字长特性是很有意义的。 这里只是以加法运算为例,说明利用高档机32位字长特性的重要性。实际上,对于其他指令也有类似的效果。对乘/除法等更复杂的指令,收到的效果会更好。
5.7.2 通用寄存器可作为指针寄存器 在第3章的3.4.1小节中,已经说明386及其后继机型除提供16位寻址外,还提供了32位寻址。在实模式下,这两种寻址方式可同时使用。在使用32位寻址时,32位通用寄存器可以作为基址或变址寄存器使用。也就是说,允许32位通用寄存器作指针寄存器用。在实模式下,段的大小被限制于64KB,这样段内的偏移地址范围应为0000~FFFFH,所以在把32位通用寄存器用作指针寄存器时,应该注意它们的高16位应为0。
提示:32位通用寄存器可用作指针寄存器,但16位通用寄存器中仍然只有BX,BP和SI,DI可用作指针寄存器。所以,下列指令是合法的:提示:32位通用寄存器可用作指针寄存器,但16位通用寄存器中仍然只有BX,BP和SI,DI可用作指针寄存器。所以,下列指令是合法的: MOV EAX,[BX] MOV EAX,[EDX] MOV AX,WORD PTR[ECX)
而下列指令是非法的: MOV AX,[DX] MOV EAX,[CX] 在386及其后继机型中,允许同一寄存器既用于基址寄存器,也用于变址寄存器。因此,下列指令也是合法的: MOV AX,[EBX][EBX]
5.7.3 与比例因子有关的寻址方式 例5.22用比例变址寻址方式编写一程序,要求把5个双字相加并保存其结果。下面给出了所编写的程序。从程序中可以清楚地看出,采用比例变址寻址方式可以直接把数组的元素下标存入变址寄存器中,而比例因子1、2、4和8正好对应于数组元素为字节、字、双字和4字的不同情况。因此,这类寻址方式为数组处理提供了极大的方便。
.386 • STACK SEGMENT STACK ‘stack’ • DW 200 DUP (?) • STACK ENDS • DATA SEGMENT • Array DD 234556H,0F983F5H,6754AE2H • DD 0C5231239H,0AF34ABC4H • result DQ ? • DATA ENDS
CODE SEGMENT START: MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX SUB EBX,EBX ;EBX寄存器清零 MOV EDX,EBX ;EDX寄存器清零 MOV EAX,EBX ;EAX寄存器清零 MOV CX, 5 ;设置循环次数为5 BACK:ADD EAX,array[EBX*4];做32位加法 ADC EDX,0 ;保存进位到EDX
INC EBX • DEC CX • JNZ BACK • MOV DWORD PTR result,EAX ;存低32位 • MOV DWORD PTR result+4,EDX ;存高32位 • MOV AX,4C00H ;返回DOS • INT 21H • CODE ENDS • END START