检测点10.1
补全程序,实现从内存1000:0处开始执行指令
assume cs:code
stack segment
db 16 dup (0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,16
mov ax,1000h
push ax
mov ax,0
push ax
retf
code ends
end start
检测点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
执行 call s 指令时首先执行类似于 push IP 的操作,再进行转移。所以,执行完 call s 指令后,栈顶存放着寄存器 IP 的值。由于 CPU 读取指令后,寄存器 IP 的值已经发生变化,为下一条指令的偏移地址,即 6。
标号 s 处指令的含义是将栈顶元素赋值给 ax,所以寄存器 ax 中的值为 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 for ptr s 相当于 push CS,push IP,所以此时栈顶元素为 IP 的值,即 8;第二栈顶元素为 CS 的值,即 1000H
标号处 s 的指令,首先栈顶元素赋值给 ax,再执行 add 指令后,ax 的值为 10H;再出栈和执行 add 指令后,寄存器 ax 的值为 1010H
检测点10.4
下面的程序执行后,ax 中的值为多少?
内存地址 机器码 汇编指令
1000:0 b8 00 00 mov ax,6
1000:2 ff d0 call ax
1000:5 40 inc ax
1000:6 mov bp,sp
add ax,[bp]
call ax 首先执行 push IP 的功能,即将 5 入栈,然后将寄存器 ax 的内容赋值给 IP 实现段内转移,此时 (IP)=5。CPU 开始执行 CS:6 处的指令,首先将寄存器 SP 的内容赋值给 BP,后面 add 指令相当于 add ax,[bp]。
寄存器 ax 的原值为 6,[bp] 默认使用段地址为寄存器 SS 的内容,即 [bp] 取的是栈顶的元素 5。最终,寄存器 ax 的值为 6+5=0BH
检测点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]
;首先执行push IP(下一条inc的偏移地址),此时SP=0EH;再执行jmp word ptr ds:[0EH],目的偏移地址由ds:[0EH]给出
;因为DS和SS指向同一片内存,且(SP)=0EH,所以ds:[0EH]相当于栈顶元素IP的值,即(IP)=(下一条inc的偏移地址),程序顺序执行
inc ax ;ax=1
inc ax ;ax=2
inc ax ;ax=3
code ends
(2) 下面的程序执行后,ax 和 bx 中的数值为多少?
mov word ptr ss:[0], offset s ;
mov ss:[2],cs
两条指令执行后,栈中情况如下
s标号值 | cs值 |
call dword ptr ss:[0]执行后
00 | 02 | 0C | 0E | ||||||||||||
s标号值 | 当前代码段cs值 | nop指令的偏移地址 | nop指令段cs值 |
assume cs:code
data segment
dw 8 dup (0)
data ends
code segment
start:
mov ax,data
mov ss,ax
mov sp,16 ;空栈,大小为16字节
mov word ptr ss:[0], offset s
;将标号s处的偏移地址赋值到ss:[0]中,即栈的第8个字
mov ss:[2],cs
;将寄存器CS的内容(标号s处的段地址)赋值到ss:[2]中,即栈的第7个字
call dword ptr ss:[0]
;首先执行push CS和push IP(后一指令nop的CS和IP),此时SP=0CH
;再执行jmp dword ptr ss:[0],目的地址由ss:[0]高地址(标号s处指令的段地址)给出、偏移地址由ss:[0]低地址(标号s处指令的偏移地址)给出
;所以,此时的jmp dword ptr ss:[0]的功能是跳转到标号s处执行
nop
s:
mov ax,offset s ;将标号s处的偏移地址赋值到AX
sub ax,ss:[0cH]
;ax=ax-ss:[0cH],ss:[0cH]的值为栈顶元素,即nop指令的偏移地址,即s.IP-nop.IP为nop指令长度,即为1
mov bx,cs
sub bx,ss:[0eH]
;bx=bx-ss:[0eH],ss:[0eH]的值为第二栈顶元素,即nop指令的段地址,即cs-nop.CS,即为0
code ends
end start
最终ax=1,bx=0