定义如下数据段
DATA SEGMENT
ORG 1000H
DATA1 DB “ABC”,-2,12H
DATA2 DW 3,’AB’,$+4
DATA3 DB 2 DUP(1,2,3 DUP(?))
DATA ENDS
试写出下列指令执行后,AX、BX、CX的值:
MOV BX,DATA2+4
MOV CH,DATA3
MOV AX,WORD PTR [DATA1+2]
MOV CL,LENGTH DATA3
SHL AX,CL
OR BX,0F00H
`ORG 1000H`` ➡ 初始化偏移地址为1000H;
其中$+4
代表获取当前地址并+4 = $+4
的值;
DATA3
中存储的数据为1 2 ? ? ? 1 2 ? ? ?
;
LENGTH
指令中:若有DUP则返回左边第一个DUP单元数,其他情况返回1;
MOV BX,DATA2+4
是将[DATA2
+ 4]放进BX中,
因为
ORG 1000H
,初始化偏移地址为1000H,所以[DATA1
]=1000H(占了4个DB),[DATA2
]=1005H
故[
DATA2
+ 4] = [1009H],而[1009H] =$+4
= 当前地址(1009H) + 4 = 100DH;
CH = 01H
[DATA1+2]
= ‘C’ = 0FEH,而 -2 = 43H;故在执行MOV AX,WORD PTR [DATA1+2]
后AX = 0FE43H
因为
DATA3
中最左边的DUP中的单元数为2,故CL=2;
左移后AX = 0F90CH
CX = 0102H
下面程序输入16位以内的二进制数(输入时回车作为输入结束),然后以有符号十进制数形式显示出来。
DATA segment
CRLF DB 0DH,0AH,24H
DATA ends
CODE SEGMENT
ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
MAIN PROC NEAR
mov ax,data
mov ds,ax
;代码从这开始插入
CALL I2
CALL D10
( )…………①
;联系上下文可知:此处应为固定结束套路
;【MOV AH,4CH】 + 【INT 21H】
INT 21H
MAIN ENDP
I2 PROC NEAR
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
XOR BX,BX
MOV CX,16
L20: MOV AH,1
INT 21H
;上面两句为从键盘输入
( )……………②
;下一句出现条件转移指令 【JE L21】
;由此可知应该填【CMP xx,yy】若xx等于yy则直接jump to L21
;L21属于另外一个处理数据的模块
;由此可得此处应该是“键盘输入循环”的条件判断.满足条件则跳转
;根据题目所说“输入时回车作为输入结束”
;故填 【CMP AL,0DH】(0DH -> 回车键)
JE L21
CMP AL,30H
JB L20
CMP AL,31H
JA L20
AND AX,01H
SHL BX,1
ADD BX,AX ;将键盘中输入的字符串存入BX
( )……………③
;键盘输入循环;
;故填【LOOP L20】
L21: MOV AX,BX 将BX的值交给AX,以免被pop操作覆盖
POP DI
POP SI
POP DX
POP CX
( )……………④
;根据上面疯狂push的尿性,此处应该疯狂倒序pop
;故填【POP BX】
RET
I2 ENDP
D10 PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
( )……………⑤
;根据下面的【OR BX,BX】可得,BX是被赋予有意义的值
;上面POP操作中并没有被涉及AX,而下一句需要更改AH
;故需要把AX的值保存,不然键盘输入白干了
;而恰好BX需要被赋予输入值来判断正负
MOV AH,9
LEA DX,CRLF ;回车换行,最后一个字符为结束标志'$'
INT 21H
OR BX,BX ;不更改BX的值但是更改符号位
JNS L100 ;判断符号位,若为正数直接跳转L100
MOV AH,2 ;否则输出负号
mov dl,"-"
INT 21H
NEG BX ;并且求补
L100: MOV AX,BX
XOR CX,CX
MOV SI,10
L101: XOR DX,DX
( )……………⑦
;SI被赋值为10D,结合程序目的可知,二进制转十进制,就是将二进制的值除以10,余数显示,商继续循环
故填【DIV SI】
PUSH DX ;将余数压栈,保存余数,以便显示;
INC CX
CMP AX,0
JNZ L101 ;商为零时退出循环
L102: POP DX
MOV AH,2
( )……………⑧
;【MOV AH,2】是输出命令;
;但DL中存的是真值,我们需要输出它的ASCII码值;
;故填【ADD DL,30H】
INT 21H
LOOP L102
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
RET
D10 ENDP
CODE ENDS
END MAIN
略
DATAS SEGMENT
;此处输入数据段代码
buf DB 300 DUP(?)
output DB 300 DUP(?)
CLRF DW 0DH,0AH,'$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
DB 128 DUP(?)
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
LEA SI,buf
mov cx,0
L20: MOV AH,1
INT 21H
CMP AL,0DH
JE L21
MOV [SI],AL
INC CX
INC SI
JMP L20
L21: MOV DX,CLRF
MOV AH,09H
INT 21H
LEA SI,buf
LEA DI,output
ADD SI,CX
;---------------------------------方案一
L32: DEC SI
mov AL,[SI]
MOV [DI],AL
INC DI
LOOP L32
LEA DX,output
MOV ah,9
INT 21H
;----------------------------------方案二
; DEC SI
; STD
;L23: LODSB
; mov dl,al
; mov ah,02
; INT 21H
; loop L23
MOV AH,4CH
INT 21H
CODES ENDS
END START
注意:当输入字符串长度超过255时,不能使用0AH 的DOS系统功能调用(INT 21H)