转移指令

Tutorial: 汇编基础 Category: C语言 Published: 2026-04-07 13:58:26 Views: 20 Likes: 0 Comments: 0
1. 转移指令 jmp: 能够(同时)修改 CS、IP
// 用法1 段间转移
jmp 2000:0

// 用法2 短转移
mov ax,2000
jmp ax
2. 使用 jmp 查看
ASSUME CS:code,DS:data,SS:stack

data segment
          db 256 dup(0)
data ends

stack segment
           db 128 dup(0)
stack ends

code SEGMENT
     start:mov ax, stack
           mov ss,ax
           mov sp,128

           jmp test1

     test2:mov bx,1000H
           mov ax,4C00H
           int 21h

     test1:mov ax,1000H
           mov ax,1001H
           mov ax,1002H
           jmp test2
code ENDS
END start
-u
0E3C:0000 B8340E        MOV     AX,0E34
0E3C:0003 8ED0          MOV     SS,AX
0E3C:0005 BC8000        MOV     SP,0080
0E3C:0008 EB08          JMP     0012
0E3C:000A BB0010        MOV     BX,1000
0E3C:000D B8004C        MOV     AX,4C00
0E3C:0010 CD21          INT     21
0E3C:0012 B80010        MOV     AX,1000
0E3C:0015 B80110        MOV     AX,1001
0E3C:0018 B80210        MOV     AX,1002
0E3C:001B EBED          JMP     000A
0E3C:001D 58            POP     AX
3. 使用 OFFSET
ASSUME CS:code,DS:data,SS:stack

data segment
          db 256 dup(0)
data ends

stack segment
           db 128 dup(0)
stack ends

code SEGMENT
     start:mov ax, stack
           mov ss,ax
           mov sp,128

           jmp test1

     test2:mov bx,OFFSET test1     ; 直接可以获取到test1的偏移地址
           mov ax,4C00H
           int 21h

     test1:mov ax,1000H
           mov ax,1001H
           mov ax,1002H
           jmp test2
code ENDS
END start
-u
0E3C:0000 B8340E        MOV     AX,0E34
0E3C:0003 8ED0          MOV     SS,AX
0E3C:0005 BC8000        MOV     SP,0080
0E3C:0008 EB08          JMP     0012
0E3C:000A BB1200        MOV     BX,0012
0E3C:000D B8004C        MOV     AX,4C00
0E3C:0010 CD21          INT     21
0E3C:0012 B80010        MOV     AX,1000
0E3C:0015 B80110        MOV     AX,1001
0E3C:0018 B80210        MOV     AX,1002
0E3C:001B EBED          JMP     000A
0E3C:001D 58            POP     AX
0E3C:001E 7408          JZ      0028
4. 关于字节
8bit = 1 byte = 1 字节 = 1111 1111 = FF = 2个十六进制数 = 2^8 = 256 = 1db
AX = FFFF = 2byte = 2 字节 = 2^16 = 65536 = 2db = 1word
11223344 = 4byte = 4字节 = 2^32 = 4db = 2word = 1dd
5. 将 s 偏移地址的指令,放到 s0 偏移地址
ASSUME CS:code,DS:data,SS:stack
; 将 s 偏移地址的指令,放到 s0 偏移地址
; -u
; 0E3C:0000 B8340E        MOV     AX,0E34
; 0E3C:0003 8ED0          MOV     SS,AX
; 0E3C:0005 BC8000        MOV     SP,0080
; 0E3C:0008 8BC3          MOV     AX,BX
; 0E3C:000A BE0800        MOV     SI,0008
; 0E3C:000D BF1600        MOV     DI,0016
; 0E3C:0010 2E            CS:
; 0E3C:0011 8B14          MOV     DX,[SI]
; 0E3C:0013 2E            CS:
; 0E3C:0014 8915          MOV     [DI],DX
; 0E3C:0016 90            NOP
; 0E3C:0017 90            NOP
; 0E3C:0018 B8004C        MOV     AX,4C00
; 0E3C:001B CD21          INT     21
; 0E3C:001D 58            POP     AX
; 0E3C:001E 7408          JZ      0028

data segment
           db 256 dup(0)
data ends

stack segment
            db 128 dup(0)
stack ends

code SEGMENT
      start:mov ax, stack
            mov ss,ax
            mov sp,128

      s:    mov ax,bx
            mov si,OFFSET s
            mov di,OFFSET s0
            mov dx,cs:[si]        ; 将 0008 处的指令 C38B 给 dx, 2个字节
            mov cs:[di],dx        ; 将 0016 处的指令 9090 替换为 C38B

      s0:   nop
            nop

            mov ax,4C00H
            int 21h

code ENDS
END start

; -u
; 0E3C:0013 2E            CS:
; 0E3C:0014 8915          MOV     [DI],DX
; 0E3C:0016 90            NOP
; 0E3C:0017 90            NOP
; 0E3C:0018 B8004C        MOV     AX,4C00
; 0E3C:001B CD21          INT     21

; -d cs:10
; 0E3C:0010  2E 8B 14 2E 89 15 90 90-B8 00 4C CD 21 58 74 08   ..........L.!Xt.

; AX=0000  BX=0000  CX=019D  DX=C38B  SP=0080  BP=0000  SI=0008  DI=0016
; DS=0E14  ES=0E14  SS=0E34  CS=0E3C  IP=0013   NV UP EI PL NZ NA PO NC
; 0E3C:0013 2E            CS:
; 0E3C:0014 8915          MOV     [DI],DX                            CS:0016=9090
; -t

; AX=0000  BX=0000  CX=019D  DX=C38B  SP=0080  BP=0000  SI=0008  DI=0016
; DS=0E14  ES=0E14  SS=0E34  CS=0E3C  IP=0016   NV UP EI PL NZ NA PO NC
; 0E3C:0016 8BC3          MOV     AX,BX
; -d cs:10
; 0E3C:0010  2E 8B 14 2E 89 15 8B C3-B8 00 4C CD 21 58 74 08   ..........L.!Xt.
-u
0E3C:0010 2E            CS:
0E3C:0011 8B14          MOV     DX,[SI]
0E3C:0013 2E            CS:
0E3C:0014 8915          MOV     [DI],DX
0E3C:0016 90            NOP ; 一个字节
0E3C:0017 90            NOP ; 一个字节
0E3C:0018 B8004C        MOV     AX,4C00
0E3C:001B CD21          INT     21
-t

AX=0000  BX=0000  CX=019D  DX=C38B  SP=0080  BP=0000  SI=0008  DI=0016
DS=0E14  ES=0E14  SS=0E34  CS=0E3C  IP=0013   NV UP EI PL NZ NA PO NC
0E3C:0013 2E            CS:
0E3C:0014 8915          MOV     [DI],DX                            CS:0016=9090
-t

AX=0000  BX=0000  CX=019D  DX=C38B  SP=0080  BP=0000  SI=0008  DI=0016
DS=0E14  ES=0E14  SS=0E34  CS=0E3C  IP=0016   NV UP EI PL NZ NA PO NC
0E3C:0016 8BC3          MOV     AX,BX
-u
0E3C:0016 8BC3          MOV     AX,BX ; 用两个字节的命令替换掉
0E3C:0018 B8004C        MOV     AX,4C00
0E3C:001B CD21          INT     21
6. jmp 原理
ASSUME CS:code,DS:data,SS:stack
; 将 s 偏移地址的指令,放到 s0 偏移地址
// -u
// 0E3C:0000 B8340E        MOV     AX,0E34
// 0E3C:0003 8ED0          MOV     SS,AX
// 0E3C:0005 BC8000        MOV     SP,0080
// 0E3C:0008 EB0E          JMP     0018
// EB = jmp 0E = 0018(jmp到的偏移地址) - 000A(jmp指令后第一个字节的地址) = 000E
// 0E3C:000A 8BC3          MOV     AX,BX
// 0E3C:000C BE0A00        MOV     SI,000A
// 0E3C:000F BF1800        MOV     DI,0018
// 0E3C:0012 2E            CS:
// 0E3C:0013 8B14          MOV     DX,[SI]
// 0E3C:0015 2E            CS:
// 0E3C:0016 8915          MOV     [DI],DX
// 0E3C:0018 90            NOP
// 0E3C:0019 90            NOP
// 0E3C:001A B8004C        MOV     AX,4C00
// 0E3C:001D CD21          INT     21

data segment
           db 256 dup(0)
data ends

stack segment
            db 128 dup(0)
stack ends

code SEGMENT
      start:mov ax, stack
            mov ss,ax
            mov sp,128
            jmp s0              ; jmp

      s:    mov ax,bx
            mov si,OFFSET s
            mov di,OFFSET s0
            mov dx,cs:[si]
            mov cs:[di],dx

      s0:   nop                ; 0018
            nop

            mov ax,4C00H
            int 21h

code ENDS
END start
7. jmp dword ptr ds:[0]
ASSUME CS:code,DS:data,SS:stack


data segment
           dd 33334444H
data ends

stack segment
            db 128 dup(0)
stack ends

code SEGMENT
      start:mov ax, stack
            mov ss,ax
            mov sp,128

            mov bx,data
            mov ds,bx
            jmp dword ptr ds:[0]

            mov ax,4C00H
            int 21h

code ENDS
END start
-u
0E2D:0000 B8250E        MOV     AX,0E25
0E2D:0003 8ED0          MOV     SS,AX
0E2D:0005 BC8000        MOV     SP,0080
0E2D:0008 BB240E        MOV     BX,0E24
0E2D:000B 8EDB          MOV     DS,BX
0E2D:000D FF2E0000      JMP     FAR [0000]
0E2D:0011 B8004C        MOV     AX,4C00
0E2D:0014 CD21          INT     21

-g B
AX=0E25  BX=0E24  CX=00A6  DX=0000  SP=0080  BP=0000  SI=0000  DI=0000
DS=0E14  ES=0E14  SS=0E25  CS=0E2D  IP=000B   NV UP EI PL NZ NA PO NC
0E2D:000B 8EDB          MOV     DS,BX

-t
AX=0E25  BX=0E24  CX=00A6  DX=0000  SP=0080  BP=0000  SI=0000  DI=0000
DS=0E24  ES=0E14  SS=0E25  CS=0E2D  IP=000D   NV UP EI PL NZ NA PO NC
0E2D:000D FF2E0000      JMP     FAR [0000]                         DS:0000=4444

-d ds:0
0E24:0000  44 44 33 33 00 00 00 00-00 00 00 00 00 00 00 00   DD33............

-t
AX=0E25  BX=0E24  CX=00A6  DX=0000  SP=0080  BP=0000  SI=0000  DI=0000
DS=0E24  ES=0E14  SS=0E25  CS=3333  IP=4444   NV UP EI PL NZ NA PO NC
3333:4444 0000          ADD     [BX+SI],AL                         DS:0E24=0A
8. 监测点 9.1
  • 程序 1
ASSUME CS:code,DS:data,SS:stack
; 若要使程序中的jmp指令执行后,
; CS:IP指向程序中的第一条指令,在data段中应该定义哪些数据
; 首先明白jmp word ptr [bx+1] 跳转到data段的第1位字节,jmp word 是段内转移,
; cs不变只要ip为0就可以了,由于是word所以,只要确定data段中12位是0就可以了


data segment
           db 1,0,0,1,1
data ends

stack segment
            db 128 dup(0)
stack ends

code SEGMENT
      start:mov ax,data
            mov ds,ax
            mov bx,0
            jmp word ptr ds:[bx+1]

            mov ax,4C00H
            int 21h

code ENDS
END start
  • 程序 2
ASSUME CS:code,DS:data,SS:stack
; 补全指令,使用 jmp 指令执行后,
; CS:IP指向程序中的第一条指令
; 总结:将 ds:[0] 替换成0, 将 ds:[2] 替换成cs


data segment
           dd 12345678H
data ends

stack segment
            db 128 dup(0)
stack ends

code SEGMENT
      start:mov ax,data
            mov ds,ax
            mov bx,0

            mov ds:[bx],bx            ; 0000 替换 5678
            mov ds:[bx+2],cs          ; 0E2D 替换1234
            jmp dword ptr ds:[0]      ; 转到替换过后的CS:IP

            mov ax,4C00H
            int 21h

code ENDS
END start
-u
0E2D:0000 B8240E        MOV     AX,0E24
0E2D:0003 8ED8          MOV     DS,AX
0E2D:0005 BB0000        MOV     BX,0000
0E2D:0008 891F          MOV     [BX],BX
0E2D:000A 8C4F02        MOV     [BX+02],CS
0E2D:000D FF2E0000      JMP     FAR [0000]
0E2D:0011 B8004C        MOV     AX,4C00
0E2D:0014 CD21          INT     21
-g 08

AX=0E24  BX=0000  CX=00A6  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0E24  ES=0E14  SS=0E23  CS=0E2D  IP=0008   NV UP EI PL NZ NA PO NC
0E2D:0008 891F          MOV     [BX],BX                            DS:0000=5678
-d ds:0 F
0E24:0000  78 56 34 12 00 00 00 00-00 00 00 00 00 00 00 00   xV4.............
-t

AX=0E24  BX=0000  CX=00A6  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0E24  ES=0E14  SS=0E23  CS=0E2D  IP=000A   NV UP EI PL NZ NA PO NC
0E2D:000A 8C4F02        MOV     [BX+02],CS                         DS:0002=1234
-t

AX=0E24  BX=0000  CX=00A6  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0E24  ES=0E14  SS=0E23  CS=0E2D  IP=000D   NV UP EI PL NZ NA PO NC
0E2D:000D FF2E0000      JMP     FAR [0000]                         DS:0000=0000
-d ds:0 F
0E24:0000  00 00 2D 0E 00 00 00 00-00 00 00 00 00 00 00 00   ..-.............
-t

AX=0E24  BX=0000  CX=00A6  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0E24  ES=0E14  SS=0E23  CS=0E2D  IP=0000   NV UP EI PL NZ NA PO NC
0E2D:0000 B8240E        MOV     AX,0E24
-d ds:0 F
0E24:0000  00 00 2D 0E 00 00 00 00-00 00 00 00 00 00 00 00   ..-.............