What does the following do?
testq %rdx, %rdx
cmovg %rcx, %rax
I understand that testq is a bitwise and between two registers, but how does it works with the flags?
What would this translate into in c?
e.g. if %rdx
would hold value 0x01
, then we'd have 0x01
& 0x01
= 0x01
, which would set
ZF = 0, SF = 0, OF = 0.
And for what I could find cmovg is performed if
˜(SF ˆ OF) & ˜ZF
which would resolve to
˜(0 ˆ 0) & ˜0 = ˜(0) & ˜0 = 1 & 1 = 1.
Would this mean that cmovg would be performed and that the corresponding c code would behave for d = %rdx
, a = rax
and c = rcx
:
if(d > 0){
a = c;
}
Or can someone maybe explain this in other words?
Additionally, i've been trying to work this assembly turning it into a corresponding c code. Currently i get a result that ends up like an infinite while loop on the testq %rdx, %rdx with jne .L4. With the content above enclosed. Anyone know what the right solution is? My current solution is this:
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
Solution (wrong):
#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);
}