1. 程式人生 > >彙編筆記_第九章

彙編筆記_第九章


title: 彙編筆記_第九章
date: 2018-12-27 21:30:12

  • 筆記
    categories:
  • 組合語言

轉移指令的原理

8086CPU的轉移指令分為以下幾類:

  • 無條件轉移指令(如:jmp
  • 條件轉移指令
  • 迴圈指令(如:loop
  • 過程
  • 中斷

操作符offset

offset的功能是 取得標號的偏移地址,是偽操作符;

assume cs:codesg
codesg segment
start:
mov ax,offset start ;相當於mov ax,0
s:
mov ax,offset s     ;相當於mov ax,3
codesg ends
end start

例題:

assume cs:codesg
codesg segment

start:
mov ax,bx   ;mov ax,bx的機器碼佔兩個位元組
mov si,offset start
mov di,offset s0

mov ax,cs:[si]
mov cs:[di],ax

s0:
nop         ;nop的機器碼佔一個位元組
nop

codesg ends
end start

jmp指令

  • jmp為無條件轉移,可以只修改IP,也可以同時修改CS和IP;
  • jmp指令要給出兩種資訊:轉移的目的地址轉移的距離(段間轉移、段內短轉移、段內近轉移)

依據位移進行轉移的jmp指令

jmp short 標號(轉到標號處執行指令)

  • 段內短轉移
  • IP的修改範圍為 -128~127

jmp short 標號的功能為:

  • (IP)=(IP)+8位位移;
  • 8位位移=“標號”處的地址-jmp指令後的第一個位元組的地址;
  • short指明此處的位移位8位位移;
  • 8位位移的範圍位-128~127,用補碼錶示;
  • 8位位移由編譯程式在編譯時算出;

CPU在執行jmp short 標號指令時只需知道轉移的位移就行;

jmp near ptr 標號

實現 段內近轉移,(IP)=(IP)+16位位移;

  • 16位位移=“標號”處的地址-jmp指令後的第一個位元組的地址;
  • near ptr指明此處的位移位16位位移;
  • 16位位移的範圍位-32769~32767,用補碼錶示;
  • 16位位移由編譯程式在編譯時算出

轉移的目的地址 在指令中 的jmp指令

上面兩個jmp指令相當於當前IP的轉移位移;

jmp far ptr 標號實現的是 段間轉移,又稱遠轉移

  • (CS)=標號所在段的段地址;
  • (IP)=標號所在段中的偏移地址;
  • far ptr指明瞭指令用標號的段地址和偏移地址修改CS和IP;

轉移地址在 暫存器 中的jmp指令

指令格式:

jmp 16位暫存器

功能:IP=(16位暫存器);

轉移指令在 記憶體 中的jmp指令

jmp word ptr 記憶體的單元地址(段內轉移)

功能:從記憶體的單元地址處開始存放著一個字,事轉移的目的偏移地址;

mov ax,0123h
mov ds:[0],ax
jmp word ptr ds;[0]

執行後(IP)=0123h

mov ax,0123h
mov [bx],ax
jmp word ptr [bx]

jmp dword ptr 記憶體單元地址(段間轉移)

mov ax,0123h
mov ds:[0],ax
mov word ptr ds:[2],0
jmp dword ptr ds:[0]

執行後(CS)=0,(IP)=0123h,CS:IP指向0000:0123

mov ax,0123h
mov [bx],ax
mov word ptr [bx+2],0
jmp dword ptr[bx]

jcxz指令

  • jcxz指令位有條件轉移指令;
  • 所有的有條件轉移指令都是 短轉移
  • 對應的機器碼中包含轉移的 位移,而不是目的地址,對IP的修改範圍都為-128~127;
  • 指令格式: jcxz 標號,(如果(cx)=0,則轉移到標號處執行);

例題:利用 jcxz 指令,實現在記憶體2000h段中查詢第一個值為0的位元組,找到後將偏移地址儲存到dx中:

assume cs:code

code segment

start:
mov ax,2000h
mov ds,ax
mov bx,0

s:
mov ch,0
mov cl,ds:[bx]
jcxz ok
inc bx
jmp short s

ok:
mov dx,bx

mov ax,4c00h
int 21h

code ends
end start

loop指令

  • loop為迴圈指令;
  • 所有的迴圈指令都是短轉移;

loop 標號:

  • (cx)=(cx)-1;
  • 如果 \((cx) \neq 0\),(IP)=(IP)+8位位移;
  • 8位位移=“標號”處的地址-loop指令後的第一個位元組的地址;

(loading)