我要将以下AT& T x86程序集转换为C:
movl 8(%ebp), %edx
movl $0, %eax
movl $0, %ecx
jmp .L2
.L1
shll $1, %eax
movl %edx, %ebx
andl $1, %ebx
orl %ebx, %eax
shrl $1, %edx
addl $1, %ecx
.L2
cmpl $32, %ecx
jl .L1
leave
但必须遵守以下框架代码:
int f(unsigned int x) {
int val = 0, i = 0;
while(________) {
val = ________________;
x = ________________;
i++;
}
return val;
}
我可以告诉那个片段
.L2
cmpl $32, %ecx
jl .L1
可以解释为while(i<32)
。我还知道x
存储在%edx
中,val
存储在%eax
中,i
存储在%ecx
中。但是,我很难将while
/ .L1
循环中的程序集转换为适合所提供的框架代码的精简高级语言。例如,shll
,shrl
,orl
和andl
只能使用其直接C等价物(<<
,>>
,{ {1}},|
),还是有一些细微差别?
是否有针对Assembly-to-C转换的标准化指南/“备忘单”?
我理解汇编到高级转换并不总是很明确,但汇编代码中肯定有一些模式可以被一致地解释为某些C操作。
答案 0 :(得分:1)
他们可以。让我们一步一步地检查循环体:例如,可以简单地使用shll,shrl,orl和andl编写 他们的直接C等价物(&lt;&gt;,&gt;,|,&amp;),还是有一些细微差别 对吗?
shll $1, %eax // shift left eax by 1, same as "eax<<1" or even "eax*=2"
movl %edx, %ebx
andl $1, %ebx // ebx &= 1
orl %ebx, %eax // eax |= ebx
shrl $1, %edx // shift right edx by 1, same as "edx>>1" = "edx/=2"
让我们
%eax *=2
%ebx = %edx
%ebx = %ebx & 1
%eax |= %ebx
%edx /= 2
ABI告诉我们(8(%ebp), %edx
)%edx是x,%eax(返回值)是val:
val *=2
%ebx = x // a
%ebx = %ebx & 1 // b
val |= %ebx // c
x /= 2
结合a,b,c:#2将a插入b:
val *=2
%ebx = (x & 1) // b
val |= %ebx // c
x /= 2
将a,b,c:#2插入b组合成c:
val *=2
val |= (x & 1)
x /= 2
最后一步:结合两个&#39; val =&#39;成为一个
val = 2*val | (x & 1)
x /= 2
答案 1 :(得分:0)
while (i < 32) { val = (val << 1) | (x & 1); x = x >> 1; i++; }
除了val,返回值应该是无符号的,并且它们不在您的模板中。该函数返回x反转的位。
你的问题的实际答案更复杂,而且非常多:没有这样的指南,它不存在,因为编译丢失了信息,你无法从汇编程序中重新创建丢失的信息。但是你经常可以做出好的猜测。