1. gzyueqian
      18529173453
      首頁 > 新聞中心 > > 正文

      對標號地址的另一種相對尋址方式

      更新時間: 2007-05-09 09:40:16來源: 粵嵌教育瀏覽量:1013


        匯編程序中, 對數據訪問時, 通常是這樣的:

      _asm{
      ...
      DATA_LABLE:
      _emit 0x87
      _emit 0xa0
      _emit 0x49
      _emit 0x90
      ...

      mov ebx, dword ptr [DATA_LABLE]
      ...
      }

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

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

      _asm{
      ...
      call FUNC_START
      FUNC_START:
      pop ebx
      sub ebx, offset FUNC_START
      mov [ebp-xx], ebx
      ...

      DATA_LABLE:
      _emit 0x87
      _emit 0xa0
      _emit 0x49
      _emit 0x90

      ...
      mov eax, [ebp-xx]
      mov ebx, dword ptr [DATA_LABLE+eax]
      ...

      }

        步驟是這樣的:

        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數據地址的錯誤引用造成程序錯誤.

      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 亚洲视频日本有码中文 | 亚洲高清专区日韩精品 | 中文字幕亚洲一区二区va在线 | 在线a天堂亚洲 | 在线鲁鲁视频免费观看 | 亚洲精品在线永久免费 |