2012-02-14 122 views
0

我對分支表有疑問。彙編程序中的分支表(Nasm)

有兩種方法來聲明這樣一個表:

    在數據扇區(DS)
  1. 在代碼區(CS)

請告訴我這種方法有什麼不同?

我已經學會了這下面的例子: 案例1:

SECTION .data 
i   dd  2; 
stab   dd  m1,m2,m3 ; branchtable for switch 

SECTION .text 
global  start 
start: 
mov ebx , [ i ]   ;  switch (i) 
cmp ebx , 1 ; 
jl end 
cmp ebx , 3 
jg end 
shl ebx , 2 ;  /∗ stab 4 Bytes ∗/
jmp [ stab+ebx −4];  
m1: ;do something..... 
.... 

案例2:

SECTION .data 
i   dd  2; 

SECTION .text 
global  start 
start: 
mov ebx , [ i ]   ;  switch (i) 
cmp ebx , 1 ; 
jl end 
cmp ebx , 3 
jg end 
shl ebx , 2 ;  /∗ stab 4 Bytes ∗/
jmp [ cs : ebx+stab −4]; branchtable in codesegment 
ALIGN 4 ;  
stab   dd  m1,m2,m3 
m1: ; do something 
.... 

我們的教授告訴我們,該方法2是更有效實現了,但爲什麼?因爲對於分支機構來說只是短暫的跳躍,我們不需要在DS中展示?

格爾茨的命運

+3

也許是因爲在第二種情況下,高速緩存可能已經預取了包含稱爲刺的表的內存位置? – 2012-02-14 19:12:36

+1

和Peter一樣,我認爲它與緩存局部性有關,但我沒有任何硬性事實。不過,我可以說,我見過的所有編譯器生成的代碼(很多)都在代碼段中有跳轉表。 – 2012-02-14 19:28:18

+0

啊沒關係,它更有效,因爲它執行'align'緩存刺的內容? – destiny 2012-02-14 19:31:15

回答

2

哪種方法更有效取決於你正在處理的處理器上,但是,我求求你的教授不同,使用CS需要一個段前綴覆蓋,使代碼更大,從而較長時間進程和更少的緩存友好。但在x86窗口(用戶空間)上,CSDS展平爲相同的線性地址空間,因此無法進行優化。

某些處理器(的Intel Atom)也必須CS較慢存取時段基是非零的,雖然在x64這消逝爲遠離FSGS所有段都將被忽略(它們的鹼是含蓄0),因到x64的平面尋址模式。 還應該注意的是,英特爾建議儘可能少使用段寄存器(這可以減輕寄存器重命名的負擔)。

+0

感謝您的評論 – destiny 2012-02-14 23:54:52