第十章 CALL和RET指令

检测点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

  1. call指令的流程:push ip,jmp 标号。
  2. push 时的ip为多少?回顾指令的执行流程:在实际执行指令前,先更新ip的偏移量+执行指令的机器码长度,结果就是下一条指令的偏移量,即先指向下一条指令的机器码,在实际执行指令内容。
  3. 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               

解:

  1. 执行完call far ptr s时:ip为0008H,先push cs,后push ip,jmp到1000:9。
  2. pop ax,ax,ax = 0008H
  3. add ax,ax,ax = 0010H
  4. pop bx,bx = 1000H
  5. 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

解:

  1. call ax:ip为5,push ip,sp = 16 - 2,jmp ax。
  2. mov bp,sp:bp = 14
  3. 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

解:

  1. ds与ss公用同一个内存段。
  2. 执行call word ptr ds:[0eh]:ip为第一句inc ax的偏移量,push ip。jmp word ptr ds:[0eh]。
  3. 0eh为十进制14,对应栈的倒数第二个字节,正为push的ip寄存器值的第一个字节。
  4. 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

解:见注释。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值