关于 call 指令的一些练习


call 指令练习 :

assume cs:code,ss:stack
; call 指令
; call指令会将 cs 压栈 , ip 压栈 , 然后再 jmp
; 因此 call 不能实现段内 短 转移

stack segment
    db 16 dup(0)
stack ends

code segment

    start:
        mov ax, stack
        mov ss, ax
        mov sp, 00A0H
        call func
        jmp finish
    func:
        mov ax, 1234H
        mov bx, 5678H
        ret
    finish:
        mov ax,4cH
        int 21H

code ends

end start

call far 指令练习 :

assume cs:code,ds:data,ss:stack
; call far ptr [Symbol]
; 远转移 , 同时修改 cs 和 ip , 皆为 16 位
; 相当于进行 : 
; push cs
; push ip
; jmp far ptr [Symbol]
; 转移的目标地址在 指令 中 , 类似于之前的 jmp far ptr [Symbol]

data segment

data ends

stack segment
    db 16 dup(0)
stack ends

code segment

    start:
        mov ax, stack
        mov ss, ax
        mov sp, 16
        mov ax, 0
        call far ptr func ; cs 压栈 , ip 压栈
        inc ax
    func:
        pop ax ; ip 弹栈
        add ax, ax
        pop bx ; cs 弹栈
        add ax, bx
        
code ends

end start

call [REGISTER] 指令练习

assume cs:code,ds:data,ss:stack

data segment

data ends

stack segment

stack ends

code segment

    start:
        mov ax, stack
        mov ss, ax
        mov sp, 00A0H
        mov ax, 000EH ; 000EH 的偏移就是 func 的物理地址
        call ax
        inc ax
    func:
        mov ax, 1234H
        mov bx, 5678H
        ret
    finish:
        mov ax,4cH
        int 21H

code ends

end start

call [Memory Address] 指令练习 :

assume cs:code,ss:stack
stack segment
    dw 8 dup(0)
stack ends
code segment
    start:
        mov ax, stack
        mov ss, ax
        mov sp, 0010H
        mov ds, ax
        call word ptr ds:[0EH]
        inc ax
        inc ax
        inc ax
code ends
end start

retf 指令练习 :

assume cs:code,ss:stack
; 补全程序 , 实现从内存 1000:0000 处开始执行指令
; ret 指令
;       段内近转移 , 也就说 , 只修改 ip 的值 , 而且修改的位数为 16 位
;       具体实现是 pop ip
; retf 指令
;       段间转移 (远转移) , 同时修改 cs 和 ip
;       具体实现是 pop ip, pop cs

stack segment
    db 16 dup(0)
stack ends

code segment

    start:
        ; 构造一个栈
        mov ax, stack
        mov ss, ax
        mov sp, 00A0H
        ; 返回地址压栈
        mov ax, 1000H
        push ax ; 首先 cs 段地址压栈
        mov ax, 0000H
        push ax ; 偏移地址 ip 压栈
        retf

    finish:
        mov ax,4cH
        int 21H

code ends

end start

下面程序执行后 , ax 的值是多少 ?

assume cs:code,ds:data,ss:stack
; 下面程序执行后 , ax 的值是多少 ?
data segment

data ends

stack segment

stack ends

code segment

    start:
        mov ax, 0000H ; ax 清零
        call func ; 读指令 , ip自增 , ip 压栈 , jmp func
        inc ax
    func:
        pop ax
        ; ax 弹栈 , 得到的值为之前被压栈的 ip 的值
        ; 也就是 inc ax 这条指令的偏移地址

code ends

end start

你可能感兴趣的:(关于 call 指令的一些练习)