令人迷惑的AT T的jmp 直接跳轉和間接跳轉

2021-06-23 03:44:23 字數 1898 閱讀 8031

最近看鏈結器原始碼中,對位置無關**pic(共享庫)的鏈結問題,發現對call和jmp很多不常用的用法,這裡試驗並總結了一下各種用法。

我們最常用的jmp形式,就是 jmp後面跟個標籤!這個沒什麼可說的!

假如標籤叫做mylabel,它的位址是0x8048377,而且有個全域性變數b,b儲存的內容就是mylabel的位址,而b的位址是0x80494a8。

即有這樣的賦值(載入)語句:

movl

$mylabel,%eax

//把mylabel的位址載入到eax暫存器中

movl

%eax,b

//把mylabel的位址載入到b中

movl

$b,%ebx

//把b的位址載入到ebx暫存器中

我們考慮下面的語句:

1. jmp

mylable 2.

jmp0x8048377 3.

jmp%eax 4.

jmp*%eax 5.

jmp*(%ebx) 6.

jmp*0x80494a8

7. jmp

*b8. jmp

$0x5

這7句jmp語句!分別都做了什麼?

1. 不用說,跳轉到mylabel標籤處繼續執行**,但是,是如何跳轉的呢?就是pc加上了mylabel標籤處對於jmp處的乙個偏移位址!可執行的二進位制**是這樣表示的:eb 03,就是說,pc+0x03就可以了。

2. 這裡,0x8048377是mylabel的位址,我以前研究過,標籤的作用,更他的位址的作用是等效的。所以,這裡的執行效果跟1中的相同。但是,還有些不一樣!這裡的二進位制**成了:e9 03 00 00 00 這裡用了32位表示了這個偏移,而在1中,只用了8位!

3. 在編譯鏈結的時候,這句**會有警告:warning:indirect jmp without '*'。間接跳轉沒有『*』符號,但是,執行起來,還是沒有錯。看一下二進位制的可執行檔案的**,發現,給補上了個『*』號!而且二進位制是:ff e0.

4. 其實,4是3的補充版,正常的形式就是4,而三是有警告的被補充的版本。

5. %ebx是b的位址,那麼(%ebx)表示ebx的值為位址,指向的地方。這裡指向了b的內容,也就是mylabel的位址!於是,化簡後,5也就等效與2,但是,二進位制表示是:ff 23。

6. 0x80494a8是b的位址,這裡看做記憶體數,那麼實質上,b指向的值是mylabel的位址,於是,化簡後同2,二進位制**是:ff 25 a8 94 04 08。

7. b是標籤,代表乙個位址,所以,這裡同6,二進位制**也同6

8. 這句話是錯誤的,jmp不支援立即數!

所以說,正確的寫法有:

1. jmp

mylable

//eb 03

2.jmp

0x8048377

//e9 03 00 00 00 3.

jmp*%eax

//ff e0

4.jmp

*(%ebx)

//ff 23

5.jmp

*0x80494a8

//ff 25 a8 94 04 08 6.

jmp*b

//ff 25 a8 94 04 08

1和2叫做間接定址,就是算偏移量的。後面沒有『*』號,而是直接乙個標籤或者位址(標籤就可以看做是位址),所以說,就是乙個直接的位址的值。間接跳轉的二進位制**是eb或者e9,是e開頭的。

3,4,5,6叫做直接定址,直接定址的標識就是這個『*』號!直接定址,就是pc直接賦值某個位址,而不是加偏移量。所以,『*』號後面的部分,其實是乙個要付給pc的值,那麼,取值的方式就好想象了!直接跳轉的二進位制**是ff開頭的。

3是暫存器直接取值;4是暫存器間接取值;5是記憶體數取值;6是標籤取值(實質上同5)。

確實,有點意思~

call同jmp指令!

令人迷惑的隱藏規則

隱藏 是指派生類的函式遮蔽了與其同名的基類函式,規則如下 1 如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無virtual 關鍵字,基類的函式將被隱藏 注意別與過載混淆 2 如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有virtual 關鍵字。此時,基類的函式被隱...

JMP段的跳轉short near far

無條件轉移指令jmp 這種跳轉指令有三種方式 短 short 近 near 和遠 far 短是指要跳至的目標位址與當前位址前後相差不超過128位元組。近是指跳轉的目標位址與當前位址在用乙個段內,即cs的值不變,只改變eip的值。遠指跳到另乙個 段去執行,cs eip都要改變。短和近在編碼上有所不同,...

jmp指令的簡單應用

一 8086cpu的轉移指令行為分類 jmp short 標號 ip ip 8位位移 8位位移範圍 128 127 jmp near ptr 標號 ip ip 16位位移 16位位移範圍 32768 32767 二 原碼,反碼,補碼的基礎概念和計算方法 在探求為何機器要使用補碼之前,讓我們先了解原碼...