call

Tutorial: 汇编基础 Category: C语言 Published: 2026-04-07 13:58:26 Views: 20 Likes: 0 Comments: 0
1. call
  • 作用:
    • call s 会将 ip = ip + call s 指令所占的字节数 作为新的 ip 存到栈中
    • 跳转到 s 标号处, ip 为 s 标号的地址, 不是栈中存的 ip
  • 与 ret 连用
assume cs:code

code segment
      start:
            mov  ax,1000H
            call s

      over:
            mov  ax,4c00h
            int  21h

      s:    mov  ax,1001H
            mov  bx,1002H
            ret               ;ip 又会被修改回来

code ends

end start
-u
0E24:0000 B80010        MOV     AX,1000
0E24:0003 E80500        CALL    000B
0E24:0006 B8004C        MOV     AX,4C00
0E24:0009 CD21          INT     21
0E24:000B B80110        MOV     AX,1001
0E24:000E BB0210        MOV     BX,1002
0E24:0011 C3            RET
0E24:0012 36            SS:
0E24:0013 7813          JS      0028
0E24:0015 FF368813      PUSH    [1388]
0E24:0019 FF368613      PUSH    [1386]
0E24:001D CF            IRET
0E24:001E FA            CLI
0E24:001F 1F            POP     DS
-t

AX=1000  BX=0000  CX=0012  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0E14  ES=0E14  SS=0E23  CS=0E24  IP=0003   NV UP EI PL NZ NA PO NC
0E24:0003 E80500        CALL    000B
-t

AX=1000  BX=0000  CX=0012  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=0E14  ES=0E14  SS=0E23  CS=0E24  IP=000B   NV UP EI PL NZ NA PO NC
0E24:000B B80110        MOV     AX,1001
-t

AX=1001  BX=0000  CX=0012  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=0E14  ES=0E14  SS=0E23  CS=0E24  IP=000E   NV UP EI PL NZ NA PO NC
0E24:000E BB0210        MOV     BX,1002
-t

AX=1001  BX=1002  CX=0012  DX=0000  SP=FFFE  BP=0000  SI=0000  DI=0000
DS=0E14  ES=0E14  SS=0E23  CS=0E24  IP=0011   NV UP EI PL NZ NA PO NC
0E24:0011 C3            RET
-t

AX=1001  BX=1002  CX=0012  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0E14  ES=0E14  SS=0E23  CS=0E24  IP=0006   NV UP EI PL NZ NA PO NC
0E24:0006 B8004C        MOV     AX,4C00
2. call far ptr s
  • 相当于

    • push cs
    • push ip
    • jmp s
  • 与 retf 连用

  • call far ptr s 后, 如果提前 pop, 就跳不回去了

assume cs:code

code segment
      start:
            call far ptr s

      over:
            mov  ax,4c00h
            int  21h

      s:
            mov  ax,1000h
            retf

code ends

end start
-u
0E24:0000 9A0A00240E    CALL    0E24:000A
0E24:0005 B8004C        MOV     AX,4C00
0E24:0008 CD21          INT     21
0E24:000A B80010        MOV     AX,1000
0E24:000D CB            RETF
0E24:000E 68            DB      68
0E24:000F 5E            POP     SI
0E24:0010 19FF          SBB     DI,DI
0E24:0012 36            SS:
0E24:0013 7813          JS      0028
0E24:0015 FF368813      PUSH    [1388]
0E24:0019 FF368613      PUSH    [1386]
0E24:001D CF            IRET
0E24:001E FA            CLI
0E24:001F 1F            POP     DS
-r
AX=0000  BX=0000  CX=000E  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0E14  ES=0E14  SS=0E23  CS=0E24  IP=0000   NV UP EI PL NZ NA PO NC
0E24:0000 9A0A00240E    CALL    0E24:000A
-t

AX=0000  BX=0000  CX=000E  DX=0000  SP=FFFC  BP=0000  SI=0000  DI=0000
DS=0E14  ES=0E14  SS=0E23  CS=0E24  IP=000A   NV UP EI PL NZ NA PO NC
0E24:000A B80010        MOV     AX,1000
-d ss:FFF0
0E23:FFF0  00 00 00 00 00 00 0A 00-24 0E 21 08 05 00 24 0E   ........$.!...$.
-t

AX=1000  BX=0000  CX=000E  DX=0000  SP=FFFC  BP=0000  SI=0000  DI=0000
DS=0E14  ES=0E14  SS=0E23  CS=0E24  IP=000D   NV UP EI PL NZ NA PO NC
0E24:000D CB            RETF
-t

AX=1000  BX=0000  CX=000E  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0E14  ES=0E14  SS=0E23  CS=0E24  IP=0005   NV UP EI PL NZ NA PO NC
0E24:0005 B8004C        MOV     AX,4C00
-d ss:FFF0
0E23:FFF0  00 00 00 10 00 00 00 10-00 00 05 00 24 0E 21 08   ............$.!.
3. 下面指令执行后, ax 中是多少
内存地址   机 器 码      汇编指令
1000:0     B8 06 00     mov ax,6
1000:2     FF D0        call ax           ; push ip = 5
1000:5     40           inc ax
1000:6                  mov bp,sp
                        add ax, ss:[bp]   ; 6 + 5 = 11 = BH
4. 对比
jmp  word ptr ds:[0]          ip = ds:[0]
修改ip

call word ptr ds:[0]          ip = ds:[0]
mov ax,1000H                  会 push 该条命令的ip, ret会pop ip

jmp  dword ptr ds:[0]         ip = ds:[2]

call dword ptr ds:[0]         会 push cs, push ip, retf 会 pop ip, pop cs
5. 监测点 10.5
  • 下面的程序执行后, 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                  ; 寄存器DS指向栈的段地址
            mov  ax,0
            call word ptr ds:[0EH]      ; 0011
      ; 首先执行push IP(下一条inc的偏移地址,0011), 此时SP=0EH(16 -2);
      ; 再执行jmp word ptr ds:[0EH], 目的偏移地址由ds:[0EH]给出
      ; 因为DS和SS指向同一片内存, 且(SP)=0EH, 所以ds:[0EH]相当于栈顶元素IP的值, 即0011, 程序顺序执行
            inc  ax                     ;ax=1
            inc  ax                     ;ax=2
            inc  ax                     ;ax=3

code ends

end start

-u
0E25:0000 B8240E        MOV     AX,0E24
0E25:0003 8ED0          MOV     SS,AX
0E25:0005 BC1000        MOV     SP,0010
0E25:0008 8ED8          MOV     DS,AX
0E25:000A B80000        MOV     AX,0000
0E25:000D FF160E00      CALL    [000E]
0E25:0011 40            INC     AX
0E25:0012 40            INC     AX
0E25:0013 40            INC     AX
6. 监测点 10.5 第二题
  • 下面的程序执行后, ax 和 bx 中的数值为多少?
assume cs:code

data segment
           dw 8 dup (0)
      ; -u
      ; 0E25:0000 B8240E        MOV     AX,0E24
      ; 0E25:0003 8ED0          MOV     SS,AX
      ; 0E25:0005 BC1000        MOV     SP,0010
      ; 0E25:0008 36            SS:
      ; 0E25:0009 C70600001A00  MOV     WORD PTR [0000],001A
      ; 0E25:000F 36            SS:
      ; 0E25:0010 8C0E0200      MOV     [0002],CS
      ; 0E25:0014 36            SS:
      ; 0E25:0015 FF1E0000      CALL    FAR [0000]
      ; 0E25:0019 90            NOP
      ; 0E25:001A B81A00        MOV     AX,001A
      ; 0E25:001D 36            SS:
      ; 0E25:001E 2B060C00      SUB     AX,[000C]
      ; 0E25:0022 8CCB          MOV     BX,CS
      ; 0E25:0024 36            SS:
data ends

code segment
      start:
            mov  ax,data
            mov  ss,ax
            mov  sp,16                          ; 空栈, 大小为16字节

            mov  word ptr ss:[0], offset s      ; 001A
      ; -d ss:0
      ; 0E24:0000  1A 00 00 00 00 00 24 0E-00 00 0F 00 25 0E 21 08   ......$.....%.!.

            mov  ss:[2],cs
      ; -d ss:0
      ; 0E24:0000  1A 00 25 0E 00 00 24 0E-00 00 14 00 25 0E 21 08   ..%...$.....%.!.

            call dword ptr ss:[0]
      ; push 0E25, 0019,跳到 0E25:001A, 也就是s标号处, nop 被跳过
      ; -d ss:0
      ; 0E24:0000  1A 00 24 0E 00 00 1A 00-25 0E 21 08 19 00 25 0E   ..$.....%.!...%.
            nop
      s:
            mov  ax,offset s                    ; ax = 001A
      ; ax=ax-ss:[0cH], ss:[0cH]的值为栈顶元素, 即nop指令的偏移地址, 即s.IP-nop.IP为nop指令长度, 即为1
            sub  ax,ss:[0cH]                    ; ax = 001A - 0019 = 1
            mov  bx,cs                          ; bx = 0E25
      ; bx=bx-ss:[0eH], ss:[0eH]的值为第二栈顶元素, 即nop指令的段地址, 即cs-nop.CS, 即为0
            sub  bx,ss:[0eH]                    ; bx = 0E25 - 0E25

code ends
end start