以下是做什么的?
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代码.目前我得到的结果最终像testq%rdx上的无限while循环,%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
#include
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);
}
Matteo Itali..
5
(从评论中移出,回复原始问题)
if(d > 0){
a = c;
}
是的,这是对的.下面我将尝试展示如何快速"解码"此模式,而不必计算标志寄存器值的所有时间.
注意:英特尔语法提前,因为比较中的操作数顺序更清晰; AT&T很相似,但操作数被颠倒了(更奇怪的角色四处传播).
"数字比较"条件代码最好在"经典"序列的上下文中理解
cmp a, b
jCC label
在CC
这里(条件码)部是指"经营者"(如,>
,<
,==
)你是在之间的比较投入a
和b
; 所以:
jg
→" Ĵ如果UMP a
是克 reater比b
";
jl
→" Ĵ如果UMP a
是升比ESS b
";
je
→" Ĵ如果UMP a
是Ë QUAL到b
";
jne
→" Ĵ如果UMP a
是Ñ OT ë QUAL到b
";
ja
→" Ĵ UMP如果a
是一个波夫b
";
jb
→ " Ĵ如果UMP a
是b elow b
";
......所有的"E"变种(jbe
,jae
,...)
(在高于/低于耦合来自更大/更小的夫妇的区别在于a
/ b
是无符号值之间的比较,g
/ l
为符号值;另外,有很多的同义词,特别je
为同义jz
AKA"跳如果零",并且jne
对于jnz
AKA"如果不是零跳";反汇编者可以生产jz
或者je
,它是相同的)
现在,来看你的情况:
test reg,reg
完全等同于cmp reg,0
(除了AF的状态,这是无关紧要的); 这很容易理解:
test
and
在操作数之间执行,并根据结果设置标志; 所以,test reg,reg
只需根据reg
(and
自己的数字是一个nop)设置标志;
cmp b,a
b-a
根据结果计算和设置标志; 因为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与零进行比较,如果它在rax中更大的移动rcx".
1> Matteo Itali..:
(从评论中移出,回复原始问题)
if(d > 0){
a = c;
}
是的,这是对的.下面我将尝试展示如何快速"解码"此模式,而不必计算标志寄存器值的所有时间.
注意:英特尔语法提前,因为比较中的操作数顺序更清晰; AT&T很相似,但操作数被颠倒了(更奇怪的角色四处传播).
"数字比较"条件代码最好在"经典"序列的上下文中理解
cmp a, b
jCC label
在CC
这里(条件码)部是指"经营者"(如,>
,<
,==
)你是在之间的比较投入a
和b
; 所以:
jg
→" Ĵ如果UMP a
是克 reater比b
";
jl
→" Ĵ如果UMP a
是升比ESS b
";
je
→" Ĵ如果UMP a
是Ë QUAL到b
";
jne
→" Ĵ如果UMP a
是Ñ OT ë QUAL到b
";
ja
→" Ĵ UMP如果a
是一个波夫b
";
jb
→ " Ĵ如果UMP a
是b elow b
";
......所有的"E"变种(jbe
,jae
,...)
(在高于/低于耦合来自更大/更小的夫妇的区别在于a
/ b
是无符号值之间的比较,g
/ l
为符号值;另外,有很多的同义词,特别je
为同义jz
AKA"跳如果零",并且jne
对于jnz
AKA"如果不是零跳";反汇编者可以生产jz
或者je
,它是相同的)
现在,来看你的情况:
test reg,reg
完全等同于cmp reg,0
(除了AF的状态,这是无关紧要的); 这很容易理解:
test
and
在操作数之间执行,并根据结果设置标志; 所以,test reg,reg
只需根据reg
(and
自己的数字是一个nop)设置标志;
cmp b,a
b-a
根据结果计算和设置标志; 因为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与零进行比较,如果它在rax中更大的移动rcx".