MOV AX,DATA MOV DS,AX MOV ES,AX MOV AX,0 LEA BX,NUB MOV DI,BX ADD DI,2 MOV AL,[BX] INC BX MUL [BX] POP DI POP BX POP AX RET SUBS ENDP CODE ENDS END
20、解决本题可以先设置两个寄存器,分别存放相对重复次数最多的字符和字符数。每当字符串中一个字符的重复次数统计完毕后,都与记录相对重复次数最多的寄存器内容进行比较,大者存入该寄存器并记录相应的字符。如此逐个判断、统计,直至字符串结束。最后将重复次数最多的字符送入CMORE单元中。 参考编程如下:
LEA BX,CSTRN ;字符串首地址送BX MOV CL,50 ;字符串长度送CL MOV DX,0 MOV AL,[BX] MOV CMORE,AL LP: MOV AL,[BX]
CALL CPP ;调统计重复字符数子程序 CMP DH,DL ;重复字符数比较 JNC NEXT MOV DH,DL MOV CMORE,AL NEXT: INC BX DEC CL
JNZ LP ;字符串未完,继续 HLT
CPP PROC MOV CH,CL MOV SI,BX INC SI
LP1: CMP AL,[SI] ;判断是否重复 JNZ NEXT1 ;不重复,转NEXT1 INC DL ;重复,DL计数器增1
NEXT1: INC SI DEC CH
JNZ LP1 ;统计未完,继续 RET ;返回 CPP ENDP 21、宏展开为:
+ ADDITION MACRO X,Y,Z PUSH AX MOV AX,X ADD AX,Y MOV Z,AX POP AX ENDM 形成宏定义ADDITION。 22、宏定义:
PUSH_TAB MACRO K PUSH TAB+K ENDM 宏调用: I=0
REPT 17 PUSH_TAB %I I=I+1
ENDM 宏展开:
+ PUSH TAB+0 + PUSH TAB+1 . .
+ PUSH TAB+16 23、程序段如下: ARRAY LABEL WORD REPT 99 DW $+2 ENDM
DW ARRAY 经汇编后得
+ DW $+2 + DW $+2
. 99个字 . + DW $+2 DW ARRAY 24、宏定义:
MAX MACRO K,A,B,C LOCAL NEXT,OUT MOV AX,A IF K—1 IF K—2 CMP C,AX JLE NEXT MOV AX,C ENDIF
NEXT:CMP B,AX JLE OUT MOV AX,B ENDIF OUT: ENDM 25、程序段如下:
INPUT: IN AL,STAT1 ;测试设备1 TEST AL,20H ;是否可用
JZ DEV2 ;不可用则转入测试设备2 CALL FAR PTR PROC1 ;可用则从设备1输入 DEV2: IN AL,STAT2 ;测试设备2 TEST AL,20H ;是否可用
JZ DEV3 ;不可用则转入测试设备3 CALL FAR PTR PROC2 ;可用则从设备2输入 DEV3: IN AL,STAT3 ;测试设备3 TEST AL,20H ;是否可用
JZ NO_INPUT ;不可用则转入NO_INPUT,如可用的输入设备
CALL FAR PTR PROC3 ;可用则从设备3输入 NO_INPUT:
第五章 32位指令及其编程 答案习题
1. 实模式:寻址采用和8086相同的16位段和偏移量,最大寻址空间1MB,最大分段64KB。可以使
用32位指令。32位的x86 CPU用做高速的8086。
保护模式:寻址采用32位段和偏移量,最大寻址空间4GB,最大分段4GB (Pentium Pre及以后为64GB)。在保护模式下CPU可以进入虚拟8086方式,这是在保护模式下的实模式程序运行环境。 2. SS,保存堆栈指针的寄存器。
3. 8个32位通用寄存器分别是:EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP。它们都可以保存数据,
暂存运算结果,也都可以存放存储器地址用于基址/变址寻址。对比16位x86 CPU只有BX/BP/SI/DI可以实现寄存器间接寻址,可见,32位通用寄存器更具有通用性。
4. 相对于原来16位指令代码格式,32位指令格式仅增加了两个关键的长度超越前缀指令。操作数
长度超越和地址长度超越,指令代码分别为66H和67H。作用如下:
操作数长度超越--根据处理器所处的工作方式不同,一条指令会默认使用16位或32位的操作数,使用操作数长度前缀后,将默认使用16/32位操作数的指令分别转为使用32/16位操作数。
地址长度超越--地址长度决定了指令中位移量的长度和有效地址计算时产生的地址位移长度。处理器在不同的工作方式下,指令会默认使用原16位地址或新的32位地址寻址存储器,使用地址长度前缀后,将默认使用16/32位地址的指令分别转为使用32/16位地址。 5. 新增的标志及其含义如下:
NT(D14):任务嵌套标志。若NT=1,表示当前执行的任务,嵌套于另一个任务中,待执行完毕时应返回原来的任务。
IOPL(D13D12):I/O特权层标志,共2位,编码表示4个特权级别,用来指定任务的I/O操作处于4个特权级别的哪一层。
VM(D17):虚拟8086方式,当32位x86 CPU处于保护方式时,如果使VM=1置位,32位x86 CPU将进入虚拟8086方式。
RF(D16):恢复标志。这个标志与调试寄存器一起使用。
AC(D18):对齐检测标志。设置是否在存储器访问时进行数据对齐检测。 VIF(D19):虚拟中断标志。IF中断允许标志的虚拟影象,与VIP连用。 VIP(D20):虚拟中断挂起标志。此标志置位指示有一个中断被挂起。
ID(D21):CPU识别标志。程序如果能够置位和复位这个标志位,则表示该微处理器支持CPU识别指令CPUID。
6. 支持原8086的16位寻址方式:
有效地址 = 基址寄存器(BX/BP)+变址寄存器(SI/DI)+8/16位常数。增加32位寻址方式:有效地址 = 基址寄存器(8个32位通用寄存器之一)+变址寄存器(除ESP的通用寄存器之一)×比例因子(1/2/4/8)+8/32位常数。BP,EBP,ESP作为基址寄存器时默认段寄存器为SS,其他为DS。数据宽度有字节(8位)、字(16位)和双字(32位)。 7. (1)立即数寻址
(2)直接寻址 (3)相对基址变址寻址 (4)带比例的变址寻址
(5)基址的带位移量的带比例的变址寻址
8. 当用PUSH指令把堆栈指针(E)SP压入堆栈时,8086/8088是将SP减2后的值进栈,而80286后
的处理器是将进栈前的(E)SP值进栈。 9. 指令如下:
LEA EAX,[EBX+ESI*2+1234H]
要保证该运算的正确必须使这条指令在32位段中执行。 10. 指令如下:
MOV DX,3FCH IN EAX,DX 11. (1)(SP)<-(SP)-2
((SP)+1,(SP))<- [BX]
(2)32位通用寄存器依次进栈,进栈次序为:EAX,ECX,EDX,EBX,指令执行前的ESP,EBP,ESI和EDI。指令执行后(SP)<- (SP)-32。 (3)将立即数4压入堆栈。
(4)将32位通用寄存器ESI弹出堆栈。
12. (1)有效地址为:00001000H + 00002000H = 00003000H。
(2)有效地址为:00001000H + 2*00002000H = 00005000H。 (3)有效地址为:4*00001000H + 00002000H + 1000H = 00007000H。
13. (1)错误。AX是16位的,而ECX是32位的。
(2)正确。因为在32位存储器寻址中变址寄存器可以是除ESP之外的任何32位通用寄存器之一,而16位存储器寻址中变址寄存器只能是SI或DI。所以在这里ECX是可以做变址寄存器的。 14. 此指令执行的操作是:DX*100H->BX。
DX与100H的乘积有可能溢出。如果溢出,那么高位部分被丢掉,并置CF=OF=1表示;如果没有溢出,则CF=OF=0。 15. 程序段如下:
MOV EDX,0 ;将EDX置0
ADD EAX,EBX ;EAX和EBX累加和到EAX
ADD EAX,ECX ;EAX和ECX累加和到EAX,则EAX中为累加和。 ADC EDX,0 ;将CF存入EDX 16. (1)EAX = 2CEFF93H
(2)EAX = 09090804H
17. 要使操作数的某些位变反,可以使用XOR指令,只要将源操作数的立即数字段的相应位置成1就
可以达到目的。此题要求第0,1位变反,可用如下指令: XOR EAX,3H 18. 编制程序如下:
MOV CX,16 ROL EAX,CX ADD EAX,EBX 19. 程序段如下:
ROR ECX,2 ;CX低2位移入了ECX的高2位 REP MOVSD ;使用CX为计数器,每次传送双字 ROL ECX,1
REP MOVSW ;传送可能余下的字 ROL ECX,1
REP MOVSB ;传送可能余下的字节
20. 指令 JECXZ label 是当ECX=0时,转移到label指定的段内偏移地址处。但要注意的是它的
偏移量只能是在-128 ~ +127范围内。
《汇编语言程序设计》试题A
一、 数制转换填空(10分)
十进制数 二进制数 十六进制数 119