将条件移动 (CMOV) 指令从汇编语言翻译成 C
Translating conditional move (CMOV) instructions from assembly into C
我正在尝试将 x86-64 程序集转换为 C 代码,但我仍然不确定条件移动。
这是汇编代码:
cmpl %esi, %edi
movl %esi, %eax
cmovge %edi, %eax // This is called a conditional move.
ret
在 C 中,会是:
if (edi < esi) { // am I supposed to change edi and esi to local variable names?
uint32_t variable1;
return ___; // what am I supposed to return?
}
我真的不确定这整件事,所以如果有人能提供帮助,那就太好了。
这实际上取决于您的 ABI,但通常,eax
是包含 return 值的寄存器。
所以更像
eax = esi;
if (edi >= esi) eax = edi;
return eax;
相当于
return (edi >= esi ? edi : esi);
条件移动 (CMOV) 指令到 C 的最简单翻译是条件运算符。类似于:
int a = (b < c) ? b : c;
这基本上允许您将 if-else 块写成一行。等效的长格式 if-else 块将是:
int a;
if (b < c)
{
a = b;
}
else
{
a = c;
}
在你的例子中,汇编代码使用了 CMOVGE 指令,这意味着 "conditionally move source to destination if flags are set to indicate greater than or equal to"。 CMP 指令用于设置标志。中间的 MOV 指令只是获取为后续 CMOV 设置的寄存器的内容,而不影响标志。
cmpl %esi, %edi ; compare the value of esi to edi, and set flags
movl %esi, %eax ; move the value of esi into eax
cmovge %edi, %eax ; if flags indicate greater than or equal to (i.e., SF == OF),
; then move the value of edi into eax
所以您的汇编代码的 C 翻译将是:
eax = (edi >= esi) ? edi : esi;
您可能希望使用描述性 变量名称,而不是在编写汇编代码时半任意选择的寄存器名称。
至于你会 return,我所知道的所有 x86 ABI 都会在 EAX 寄存器中保留函数的 return 值。因此,汇编代码 returning EAX 中剩余的任何值。 (这就是为什么需要中间的 MOV 指令——以确保 return 值在 EAX 中结束。)因此,在转换为 C 时,您可以简单地使用以下一行代码:
return (edi >= esi) ? edi : esi;
请放心,任何编译器都会将其翻译成等效的汇编代码!
我正在尝试将 x86-64 程序集转换为 C 代码,但我仍然不确定条件移动。
这是汇编代码:
cmpl %esi, %edi
movl %esi, %eax
cmovge %edi, %eax // This is called a conditional move.
ret
在 C 中,会是:
if (edi < esi) { // am I supposed to change edi and esi to local variable names?
uint32_t variable1;
return ___; // what am I supposed to return?
}
我真的不确定这整件事,所以如果有人能提供帮助,那就太好了。
这实际上取决于您的 ABI,但通常,eax
是包含 return 值的寄存器。
所以更像
eax = esi;
if (edi >= esi) eax = edi;
return eax;
相当于
return (edi >= esi ? edi : esi);
条件移动 (CMOV) 指令到 C 的最简单翻译是条件运算符。类似于:
int a = (b < c) ? b : c;
这基本上允许您将 if-else 块写成一行。等效的长格式 if-else 块将是:
int a;
if (b < c)
{
a = b;
}
else
{
a = c;
}
在你的例子中,汇编代码使用了 CMOVGE 指令,这意味着 "conditionally move source to destination if flags are set to indicate greater than or equal to"。 CMP 指令用于设置标志。中间的 MOV 指令只是获取为后续 CMOV 设置的寄存器的内容,而不影响标志。
cmpl %esi, %edi ; compare the value of esi to edi, and set flags
movl %esi, %eax ; move the value of esi into eax
cmovge %edi, %eax ; if flags indicate greater than or equal to (i.e., SF == OF),
; then move the value of edi into eax
所以您的汇编代码的 C 翻译将是:
eax = (edi >= esi) ? edi : esi;
您可能希望使用描述性 变量名称,而不是在编写汇编代码时半任意选择的寄存器名称。
至于你会 return,我所知道的所有 x86 ABI 都会在 EAX 寄存器中保留函数的 return 值。因此,汇编代码 returning EAX 中剩余的任何值。 (这就是为什么需要中间的 MOV 指令——以确保 return 值在 EAX 中结束。)因此,在转换为 C 时,您可以简单地使用以下一行代码:
return (edi >= esi) ? edi : esi;
请放心,任何编译器都会将其翻译成等效的汇编代码!