[英]Assembly testq and cmovg instruction
以下是做什么的?
testq %rdx, %rdx
cmovg %rcx, %rax
據我所知,testq是兩個寄存器之間的位運算符和,但它是如何與標志的作品? 這將在c中轉換為什么? 例如,如果%rdx
將舉行值0x01
,那么我們就會有0x01
和0x01
= 0x01
,這將設置
ZF = 0, SF = 0, OF = 0.
而對於我能找到cmovg是,如果執行
˜(SF ˆ OF) & ˜ZF
這將解析
˜(0 ˆ 0) & ˜0 = ˜(0) & ˜0 = 1 & 1 = 1.
將這個意思將被執行的cmovg和相應的C代碼將表現為d = %rdx
, a = rax
和c = rcx
:
if(d > 0){
a = c;
}
或者有人可以也許換句話說解釋一下嗎?
另外,我一直在努力工作,本次大會將其轉換成對應的C代碼。 目前,我得到的是像一個無窮最終結果while循環testq%RDX上,%的RDX與JNE .L4。 附上以上內容。 任何人都知道正確的解決方案是什么? 我當前的解決方案是這樣的:
p:
movq (%rdi), %rdx
testq %rdx, %rdx
je .L5
movl $0, %eax
.L4:
leaq (%rax,%rdx), %rcx
testq %rdx, %rdx
cmovg %rcx, %rax
addq $8, %rdi
movq (%rdi), %rdx
testq %rdx, %rdx
jne .L4
ret
.L5:
movl $0, %eax
ret
解決方法(錯誤):
#include<stdlib.h>
#include <stdio.h>
int func(int *rdi){
int rdx = *rdi;
if(rdx == 0){
int rax = 0;
return rax;
}
int rax = 0;
do {
int rcx = rax + rdx;
if(rdx > 0){
rax = rcx;
}
rdi += 8;
rdx = *rdi;
} while(rdx != 0);
return rax;
}
int main(int argc, char const *argv[]) {
int var = 20;
int *ip;
ip = &var;
func(ip);
}
(從評論中移出,回答原始問題)
if(d > 0){ a = c; }
是的,這是正確的。 下面我會盡力展示如何迅速“解碼”這個模式,而不必計算所有時代的標志寄存器值。
注意 :Intel語法在前,因為在比較中操作數順序更清晰; AT&T 與之類似,但是操作數相反 (並且散布了更多的奇怪字符)。
在“經典”序列的上下文中,最好能理解“數字比較”條件代碼
cmp a, b
jCC label
這里的CC
(條件代碼)部分是指您要在a
和b
之間進行比較的“運算符”(如>
, <
, ==
); 所以:
jg
→ “如果j UMP a
是克 reater大於b
”; jl
→ “如果j UMP a
比升 ESS b
”; je
→ “ĴUMP如果a
為e QUAL到b
”; jne
→ “如果j UMP a
為n OTëQUAL到b
”; ja
→ “如果j UMP a
是波夫b
”; jb
→ “ĴUMP如果a
為b elow b
”; jbe
, jae
,...) (上方/下方對與上方/下方對的區別在於a
/ b
用於比較無符號值, g
/ l
表示有符號值;此外,還有很多同義詞 ,特別是je
是jz
AKA的同義詞“如果為零則跳轉”,以及jnz
AKA的jne
為“如果非零則跳轉”;反匯編程序可能會生成jz
或je
,這是相同的)
現在,來看您的情況:
test reg,reg
完全等同於cmp reg,0
( 除了AF的狀態無關); 這很容易理解:
test
在操作數之間執行and
,並根據結果設置標志; 所以, test reg,reg
只是根據設置標志reg
( and
荷蘭國際集團的數與本身是一個NOP); cmp b,a
計算ba
並根據結果設置標志; 鑒於b-0 == b
, cmp b,0
只是設置根據標志b
,正如test b,b
。 cmovg
是實例cmovCC
指令,與條件代碼g
,即,“移動如果g reater”。 所以,你的
test rdx,rdx
cmovg rax,rcx
相當於
cmp rdx,0
cmovg rax,rcx
這清楚地讀作“零比較RDX,如果它是更大的舉動RCX在RAX”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.