1. 程式人生 > >17-equ偽指令和jmp指令

17-equ偽指令和jmp指令

1. equ指令

equ指令(英文為:equal),在Nasm彙編器中是一條偽指令。我們知道偽指令不能直接執行,需要經過編譯器處理轉換成純彙編指令。類似equ指令的語法,在很多程式語言中都存在,有的叫做定義常量,比如我們學習C語言會接觸到一個#define的語法,跟equ指令的作用是一樣的,因為equ指令的本質就是替換

 

直接上程式碼吧:

mov ax,100
mov bx,100
mov cx,100  

times 510-($-$$) db 0x00
dw 0xAA55 

上述程式碼中,依次將暫存器ax,bx,cx的值都修改為100了。考慮這麼一種情況,如果我們要把暫存器的值全部修改為200的話就很不方便,這僅僅是3個數據,如果是30或300,甚至更多的資料呢?在這種情況下,使用equ偽指令顯然就簡單多了。

 

使用equ指令修改程式碼:

num equ 110		
mov ax,num 
mov bx,num 
mov cx,num 

times 510-($-$$) db 0x00
dw 0xAA55 

編譯之後如下圖所示:

偽指令編譯之後就消失了,同時會把num替換成立即數110(十六進位制為0x6E),所以這就是個替換的過程。

equ指令宣告的任何數字是不佔用記憶體的,因為它是一個立即數,是直接從指令中得到,而不是要從記憶體中定址得到這個數。另外通過equ指令給立即數賦值有意義的名稱,還可以提高程式碼的可讀性和可維護性。

 

2. jmp指令的各種寫法

jmp指令是一個跳轉指令,通過下面的程式碼我們來看一下jmp指令的跳轉過程:

Mark:
mov ax,0x1111    ;3
mov bx,0x2222    ;6
mov cx,0x3333    ;9

jmp near Mark    ;12

首先我們知道其實地址是0x07c00,以上三條指令各自佔用3個位元組,而jmp指令也佔用3個位元組,所以當執行jmp指令時,就會計算與標號Mark的距離,然後減去12,回到Mark標號的位置(即起始地址0x07c00)處開始執行了。

在jmp指令中,near是附近的意思。但是jmp near指令不修改CS暫存器,隻影響IP暫存器,通知IP暫存器增加,或者減去一個固定數值: 16位的有符號數。

near因為不修改段暫存器,隻影響IP暫存器,所以通常把jmp near叫做段內轉移,因為它只在一個段內轉移。

 

還有一種寫法:

jmp 0x0000:0x7C00	;這種寫法是直接修改cs和ip暫存器

這種寫法不叫段內轉移。