對標號位址的另一種相對定址方式

2021-04-16 12:48:14 字數 1066 閱讀 8407

匯程式設計序中, 對資料訪問時, 通常是這樣的:

_a**

其中, 當程式編譯之後, mov指令中的data_lable標號位址會被轉成乙個絕對位址. 而有時絕對位址這一點可能會對這樣一種需求帶來障礙: 我們希望自己寫的彙編**不管被放在哪塊位址空間中都是能正常執行的, 就象我們寫高階語言中的那些函式一樣, 函式位置可以被隨意放置, 絲毫不會影響函式本身的功能使用. 當然, 不得不指出的是, 儘管要求的是同樣功能, 但彙編與高階語言之間在這方面的實現卻相去甚遠. 高階語言的函式在最終被編譯之後, 其函式位址也是固定的絕對位址, 而我們所想要用彙編實現的才是真正的"可被任意放置"的二進位制執行塊.

借用call指令, 可以實現執行期標號位址的相對定址, 大致的思路如下:

_a**

步驟是這樣的:

1.首先, 在彙編功能塊或函式首部, 使用以下語句取得執行期位址與編譯位址的修正差值.

call func_start

func_start:

pop ebx

sub ebx, offset func_start

mov [ebp-xx], ebx

略作解釋: call 函式會將eip暫存器壓入堆疊, 之後用"pop ebp"是將eip值賦給ebp, 而eip表示的是"下一條語句的位址", 在這裡, 當程式執行到"call func_start"時, 它表示的是以標號"func_start:"開始的"pop ebx"指令起始位址. 而另一方面, sub指令中的"offset func_start", 在編譯時, offset會被轉成乙個絕對位址. 這樣,通過sub操作, 就獲得了此段**在編譯期和執行期關於指令位址的修正值. 下面的這句: "mov [ebp-xx], ebx", 實際上只是錦上添花, 它把這個值儲存在了某乙個自定義的函式區域性變數空間內, 以備後續語句方便引用.

2.相應的, 對標號資料的引用就變成這樣的兩句:

mov eax, [ebp-xx]

mov ebx, dword ptr [data_lable+eax]

對於彙編函式中的此類**進行這樣的處理後, 此段二進位制執行塊就可以被放置在任意地方而不致因為對data_lable資料位址的錯誤引用造成程式錯誤.

對標號位址的另一種相對定址方式

匯程式設計序中,對資料訪問時,通常是這樣的 a 其中,當程式編譯之後,mov指令中的data lable標號位址會被轉成乙個絕對位址.而有時絕對位址這一點可能會對這樣一種需求帶來障礙 我們希望自己寫的彙編 不管被放在哪塊位址空間中都是能正常執行的,就象我們寫高階語言中的那些函式一樣,函式位置可以被隨...

對標號位址的另一種相對定址方式

匯程式設計序中,對資料訪問時,通常是這樣的 a 其中,當程式編譯之後,mov指令中的data lable標號位址會被轉成乙個絕對位址.而有時絕對位址這一點可能會對這樣一種需求帶來障礙 我們希望自己寫的彙編 不管被放在哪塊位址空間中都是能正常執行的,就象我們寫高階語言中的那些函式一樣,函式位置可以被隨...

for迴圈的另一種方式

語法 for expr1 expr2 expr3 do done 解釋 expr1 控制變數的初始值 expr2 判定什麼時候退出迴圈 expr3 修正這個變數的值 範例 計算1到100之間的數值的和 這裡面 有倆種方式 最普通的是我們想到的是 1到100之間的數列,另一種是今天的小知識點的運用 這...