1. 程式人生 > >王爽第九章依據位移進行轉移的jmp指令

王爽第九章依據位移進行轉移的jmp指令

assume cs:code

code segment 
	
start:	mov ax,0
	<span style="font-family: Arial, Helvetica, sans-serif;">jmp short s</span>
<span style="white-space:pre">	</span>add ax,1
s:	inc ax
	
mov ax,4c00h
int 21h
code ends
	
end start

其中

jmp short s
相當於
jmp short 8



機器碼eb之後的是位移

1、段內近轉移的8位位移 = 標號處的地址 - jmp 指令後的第一個指令的地址

2、short 指明此處是的位移是8位位移

3、8位位移的範圍為-128 ~ 127,用補碼來表示-128 = 80 127=7f

4、8位位移由編譯程式在編譯中算出

assume cs:code

code segment 
	
start:	mov ax,0
	mov bx,0
	jmp far ptr s
	db 256 dup (0)
s:	add ax,1
	inc ax
	
mov ax,4c00h
int 21h
code ends
	
end start
其中
jmp far ptr s
的機器碼要佔5個位元組
mov ax,0
mov bx,0
的機器碼佔6個位元組
db 256 dup (0)
佔256個位元組

一共267個位元組,16進位制10b

還是同一個段



cs沒有變ip = 6 + 5 + 256 = 267 十六進位制 10b

010b 為IP 

1ca5 為cs

assume cs:code

data segment
dd 0
data ends
code segment 
	
start:	mov ax,data
	mov ds,ax
	mov bx,0
	jmp word ptr [bx+1]
mov ax,4c00h
int 21h
code ends
	
end start
其中
jmp word ptr [bx+1]
功能:從記憶體單元地址處開始存放一個字,是轉移的目的偏移地址

assume cs:code

data segment
dd 12345678h
data ends
code segment 
	
start:	mov ax,data
	mov ds,ax
	mov bx,0
	mov [bx],bx
	mov [bx+2],cs
	jmp word ptr ds:[0]
mov ax,4c00h
int 21h
code ends
	
end start
其中 
jmp word ptr ds:[0]
cs= ds[2] ip= ds[1]
功能:從記憶體單元地址處開始存放著兩個字,高地址處的字是轉移的目的的地址,低地址處是轉移的目的偏移地址

(cs) = (記憶體單元地址 + 2)

(ip) = ((記憶體單元地址)


assume cs:code
code segment 

start:	mov ax,2000
	mov ds,ax
	mov bx,0
	s:mov cl,ds:[bx]	
	mov ch,0
	jcxz ok
	inc bx
	jmp short s
	ok:mov dx,bx
mov ax,4c00h
int 21h
code ends
	
end start
其中
jcxz ok
的作用 當(cx) = 0 時, (ip) = (ip) + 8位位移

8位位移 = 標號處的地址 - jcxz 指令後的第一個位元組的地址

8位位移的範圍為 -128 ~ 127 ,用補碼錶示

8位位移由編譯程式在編譯時算出

當(cx) ≠ 0時, 什麼都不做(程式向下執行)

jcxz 標號的作用相當於:

if ((cx) == 0) jmp short 標號



cx = 0 ip=c

8位位移 = 11 - c -2 =3

assume cs:code
code segment 

start:	mov ax,2000
	mov ds,ax
	mov bx,0
s:	mov cl,[bx]
	mov ch,0
	inc cx
	inc bx
	loop s
	ok:dec bx
	mov dx,bx
	
mov ax,4c00h
int 21h
code ends
	
end start
其中
loop s
loop 指令為迴圈指令

操作

(1) (cx) = (cx) - 1

(2) 如果 (cx) ≠ 0, (ip) = (ip) + 8 位位移

8位位移 = 標號處地址 - loop指令後的第一個位元組的地址

8位位移的範圍為 -128 ~ 127,用補碼錶示

8位位移由編譯程式在編譯時算出

如果(cx) = 0 ,什麼都不做



e+1 = f 

f6 + 8 + 2 = 100  f6是-10 的補碼

標號處 08loop後 12    08-12 = f6

assume cs:code
code segment 
	
	mov ax,4c00h
	int 21h
start:	mov ax,0
s:	nop
	nop

	mov di,offset s
	mov si,offset s2
	mov ax,cs:[si]
	mov cs:[di],ax

s0:	jmp short s

s1:	mov ax,0
	int 21h
	mov ax,0
	
s2:	jmp short s1
	nop
code ends
	
end start
其中
mov di,offset s
mov si,offset s2
mov ax,cs:[si]
mov cs:[di],ax
jmp short s1

位移位10個位元組

複製到
nop
nop
同樣位移為10個位元組

這條指令會直接讓程式中斷

assume cs:code,ds:data
data segment
  db 'W','e','l','c','o','m','e',' ','t','o',' ','m','a','s','m','!'
data ends
code segment
start:
  mov ax,data
  mov ds,ax
  
  mov ax,0b800h;b800是顯示緩衝區的首地址
  mov es,ax;在顯示緩衝區中,偶地址存放字元,奇地址存放字元的顏色屬性,預設07,黑底白字
  mov bx,0720h;十六進位制a0h表是第1行,第12行就是a0h*bh=6e0h,一行放80個字元,放到中間的話
  ;就40個字元-16個字元的一半=32個字元,一個字元要兩個位元組,所以偏移地址加上64,也就是40h,
;40h+6e0h=720h
  mov bp,0;從第一個字元讀取
  mov cx,16;空格也算字元
s:  mov al,ds:[bp];放字元到暫存器
  mov ah,2h;放字元的顏色屬性,顯示綠色,10
  mov es:[bx],ax;放字元和字元顏色屬性到記憶體
  
  mov al,ds:[bp]
  mov ah,24h;綠底紅字 100100
  mov es:[bx+160],ax ;80個字元佔160個位元組,到第二行
  
  mov al,ds:[bp]
  mov ah,71h;1110001 白底藍字
  mov es:[bx+320],ax ;80個字元佔160個位元組,到第三行
  
  add bx,2;一次送了2個位元組,按字來讀取
  inc bp;資料段按位元組儲存,bp就按位元組讀取
  loop s;迴圈16次
 
  mov ax,4c00h
  int 21h
code ends
end start