以下是做什么的?
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<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);
}
答案 0 :(得分:5)
(从评论中移出,回复原始问题)
if(d > 0){ a = c; }
是的,这是对的。下面我将尝试展示如何解码&#34;这种模式很快,无需计算标志寄存器值的所有时间。
注意:英特尔语法提前,因为它在比较中的操作数顺序更清晰; AT&amp; T类似但与操作数相反(并且更多奇怪的字符在周围传播)。
&#34;数字比较&#34;条件代码最好在&#34; classic&#34;的背景下理解。序列
cmp a, b
jCC label
这里的CC
(条件代码)部分是指&#34;运算符&#34; (例如,>
,<
,==
)您在a
和b
之间进行比较;这样:
jg
→&#34; j ump如果a
g 比b
&#34;; < / LI>
jl
→&#34; j ump如果a
l ess比b
&#34 ;; < / LI>
je
→&#34; j ump,如果a
e 符合b
&#34 ;; < / LI>
jne
→&#34; j 如果a
n e 符合{{{ 1}}&#34 ;; b
→&#34; j 如果ja
a bove a
&#34 ;; b
→&#34; j ump如果jb
b elow a
&#34 ;; b
,jbe
,...)(上面/下面的情侣不同于较大/较少情侣jae
/ a
用于比较无符号值,b
/ g
表示有符号值另外,还有a lot of synonyms,特别是l
是je
AKA的同义词&#34;如果为零则跳转为#34;以及jz
为jne
} AKA&#34;跳跃,如果不是零&#34 ;;反汇编者可以产生jnz
或jz
,它是相同的)
现在,来看你的情况:
je
完全等同于test reg,reg
(apart from the status of AF,这是无关紧要的);这很容易理解:
cmp reg,0
在操作数之间执行test
并根据结果设置标志;所以,and
只根据test reg,reg
设置标记(reg
一个数字本身就是一个nop); and
计算cmp b,a
并根据结果设置标志;鉴于b-a
,b-0 == b
只根据cmp b,0
设置标记,与b
完全相同。test b,b
是cmovg
指令的一个实例,条件代码为cmovCC
,即&#34;如果 g reater&#34;则移动。 所以,你的
g
相当于
test rdx,rdx
cmovg rax,rcx
明确地将其读作&#34;将rdx与零进行比较,如果它在rax&#34;中移动rcx更大。