检测点10.1
补全程序,实现从内存1000:0000处开始执行指令
assume cs:code,ss:stack
stack segment
db 16 dup (0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,16
mov ax,()
push ax
mov ax,()
push ax
retf
code ends
end start
解:1000H、0H。reft从栈pop的顺序为:pop ip - pop cs
检测点10.2
下面的程序执行后,ax中的数值为多少?
内存地址: 机器码 汇编指令
1000: 0 b8 00 00 mov ax,0
1000:3 e8 01 00 call s
1000: 6 40 inc ax
1000:7 58 s:pop ax
解:ax = 6
- call指令的流程:push ip,jmp 标号。
- push 时的ip为多少?回顾指令的执行流程:在实际执行指令前,先更新ip的偏移量+执行指令的机器码长度,结果就是下一条指令的偏移量,即先指向下一条指令的机器码,在实际执行指令内容。
- jmp到s标号处pop,结果为6
检测点10.3
下面的程序执行后,ax中的数值为多少?
内存地址 机器码 汇编指令
1000:0 b8 00 00 mov ax,0
1000:3 9a 09 00 00 10 call far ptr s
1000:8 40 inc ax
1000:9 58 s:pop ax
add ax,ax
pop bx
add ax,bx
解:
- 执行完call far ptr s时:ip为0008H,先push cs,后push ip,jmp到1000:9。
- pop ax,ax,ax = 0008H
- add ax,ax,ax = 0010H
- pop bx,bx = 1000H
- add ax,bx,ax = 1010H
检测点10.4
下面的程序执行后,ax中的数值为多少?
内存地址 机器码 汇编指令 执行后情况
1000:0 b8 06 00 mov ax,6 (ax)=6,ip指向1000:3
1000:3 ff d0 call ax push ip(此时IP值为5),ip转移指向1000:6
1000:5 40 inc ax
1000:6 58 mov bp,sp (bp)=(sp)=fffeh
add ax,[bp] (ax)=6+(ss:bp)=6+5=0bh
解:
- call ax:ip为5,push ip,sp = 16 - 2,jmp ax。
- mov bp,sp:bp = 14
- add ax,[bp]:ax = 000BH(6 + ss:[14])
检测点10.5
(1)下面的程序执行后,ax中的数值为多少?
assume cs:code
stack segment
dw 8 dup (0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ds,ax
mov ax,0
call word ptr ds:[0eh]
inc ax
inc ax
inc ax
mov ax,4c00h
int 21h
code ends
end start
解:
- ds与ss公用同一个内存段。
- 执行call word ptr ds:[0eh]:ip为第一句inc ax的偏移量,push ip。jmp word ptr ds:[0eh]。
- 0eh为十进制14,对应栈的倒数第二个字节,正为push的ip寄存器值的第一个字节。
- ax=3
(2)下面的程序执行后,ax和bx中的数值为多少?
assume cs:codesg
stack segment
dw 8 dup(0)
stack ends
codesg segment
start:
mov ax,stack
mov ss,ax
mov sp,10h
mov word ptr ss:[0],offset s ;(ss:[0])=001AH
mov ss:[2],cs ;(ss:[2])=cs
call dword ptr ss:[0] ;cs入栈,ip=19H入栈,jmp cs:1AH
;(ss:[14])=cs,(ss:[12])=ip
nop
s: mov ax,offset s ;ax=1AH
sub ax,ss:[0ch] ;ax=1AH-(ss:[0ch])=1AH-19H=1
mov bx,cs ;bx=cs
sub bx,ss:[0eh] ;bx=cs-(ss:[0eh])=cs-cs=0
mov ax,4c00h
int 21h
codesg ends
end start
解:见注释。