跳轉指令
條件分支
迴圈switch語句
總結自《深入理解計算機系統》第三版
cpu還維護一組單個位的條件碼暫存器,用來描述最近的算術和邏輯操作的屬性。常用
cf:無符號溢位
of:有符號溢位
zf:零標誌
sf:符號標誌
注意:test指令與and指令一樣,而不改變dest暫存器
用法:兩個運算元是一樣的,例如testq %rax,%rax用來檢測%rax是負數、零、正數
假設temp=test %rax,%rax
set指令的目的運算元是低位單位元組暫存器,或是乙個位元組的記憶體位置(指令將這個位元組設定為0或1,為得到32或64位結果,將高位清零)
機器**對於有符號和無符號兩種情況都使用一樣的指令,許多算術運算對於無符號和補碼算術有一樣的位級操作。對於右移、除法、乘法和不同的條件碼組合需使用的不同的版本。
兩種指令
目的地用乙個標號(label)指明
jmp .l1
目的地為暫存器
將目標指令的位址與緊跟在跳轉指令後面那條指令的位址之間的差作為編碼。
還有一種編碼方式是給出絕對位址,用4位元組直接指定目標,彙編器和鏈結器會選擇適當編碼。
movq %rdi,
%rax
jmp .l2
.l3:
sarq %rax
.l2:
testq %rax,
%rax
jg .l3
rep;ret
彙編產生「.o」格式反彙編版本
0:48
89 f8 ;mov %rdi,
%rax
3: eb 03
;jmp 8
0x8>5:
48 d1 f8 ;sar %rax8:
4885 c0 ;test %rax,
%rax
b:7f f8 ;jg 5
0x5>
d: f3 c3 ;repz retq
第二行的跳轉目標是0x8,指令中的位元組編碼為0x03,它與第三行位址0x5相加為0x8,,第5行跳轉目標是0x5,指令中的位元組編碼為0xf8(十進位制-8)
注意:程式計數器的值是跳轉指令後面的那條指令,而不是跳轉指令本身位址。
使用pc-relative定址好處
指令編碼簡潔
當指令被重定位到不同的位址時,跳轉目標的編碼不需要改變。
c語言的if-else語句
if
(test-expr)
then-statement
else
else
-statement
彙編形式
t-test-expr;if(
!t)goto false;
then-statement
goto done;
false:
else
-statement
done:
控制的條件轉移,當條件滿足時,程式沿著一條路徑,不滿足時,條件沿著另一條路徑,在現代處理器上很低效。
處理器通過流水線(pipelining)獲得高效能,流水線中一條指令的處理經過一系列階段,每個階段執行所需操作的一部分(例如,從記憶體取指令,確定指令型別,從記憶體讀資料,執行算術運算,向記憶體寫資料,更新程式計數器),通過重疊連續指令的步驟獲得高效能。這要保證能過事先確定要執行的指令序列,保證流水線裡充滿了待執行的指令。而條件跳轉,需要分支條件求值後才能決定路徑。處理器會採用分支**邏輯猜測指令路徑。錯誤的**跳轉,要求處理器丟掉之前的指令,再用正確的位置填充流水線,大約15~30個時鐘週期。
處理器無需**測試結果就可以執行條件傳送,處理器讀源值,檢查條件碼,看是否需要更新目的暫存器。
c語言形式
v=test-expr?then-expr:
else
-expr;
條件傳送形式
v=then-expr;
ve=else
-expr;
t=test-expr;if(
!t) v=ve;
例子
存在的問題
do-while迴圈
do
body-statement
while
(test-expr)
;
彙編形式
loop:
body-statement
t=test-expr;
if(t)
goto loop;
while迴圈
while
(test-expr)
body-statement
彙編形式
goto test;
loop:
body-statement
test:
t=test-expr;
if(t)
gpto loop;
考官語句通過整數索引值進行多重分支,使用跳轉表(位址陣列),表項i是乙個**段的位址,這個**段的實現相當於開關索引值等於i時程式的路徑。這裡直接給出書上的例子。
x86 64彙編呼叫過程簡介
過程是軟體中一種很重要的抽象。它提供了一種封裝 的方式,用一組指定的引數和乙個可選的返回值實現了某種功能。設計良好的軟體用過程作為抽象機制,隱藏某個行為的具體實現,同時又提供清晰簡潔的介面定義,說明要計算的是哪些值,過程會對程式狀態產生什麼樣的影響。不同程式語言中,過程的形式多樣 函式,方法,子例程...
x86 64 核心堆疊
switch to.h中 define switch to prev,next,last do while 0 會切換將切換前的程序核心堆疊指標用彙編movl esp,prev sp 儲存。其中被儲存的位址 prev sp 是prev thread.sp 切換後的程序esp從儲存中恢復使用彙編 mo...
linux 啟動 過程 學習 (x86 64
1.arch x86 boot header.s kernel setup 從 start開始。設定 stack,bss,最後跳轉到 arch x86 boot main.c。2.在main函式中,把kernel setup header 拷貝到 struct setup header,之後初con...