匯程式設計序中, 對資料訪問時, 通常是這樣的:
_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之間的數列,另一種是今天的小知識點的運用 這...