2010-10-24 100 views
8

所以我有以下汇编语言代码,我需要转换成C.我困惑了几行代码。汇编语言到C

我知道这是一个for循环。我在每一行添加了我的评论。

我觉得for循环是这样

for (int i = 1; i > 0; i << what?) { 
    //Calculate result 
} 

什么是测试条件?我该如何改变它?

看看汇编代码,变量'n'做什么?

这是英特尔的x86所以格式是MOVL =源,什特

movl 8(%ebp), %esi  //Get x 
    movl 12(%ebp), %ebx //Get n 
    movl $-1, %edi   //This should be result 
    movl $1, %edx   //The i of the loop 
.L2: 
    movl %edx, %eax 
    andl %esi, %eax 
    xorl %eax, %edi  //result = result^(i & x) 
    movl %ebx, %ecx  //Why do we do this? As we never use $%ebx or %ecx again 
    sall %cl, %edx   //Where did %cl come from? 
    testl %edx, %edx  //Tests if i != what? - condition of the for loop 
    jne .L2    //Loop again 
    movl %edi, %eax  //Otherwise return result. 
+1

testl%edx,%edx检查edx是否为0,然后jne - 如果不为零则跳转。 – 2010-10-24 12:20:38

+0

你对哪条线感到困惑?在C中,for循环用于(;;){} – 2010-10-24 12:33:23

+0

为什么要将legacy asm转换为C? – 2010-10-24 12:34:33

回答

14

sall %cl, %edx移位%EDX通过%cl位向左。 (%cl,仅供参考,为%ecx的低字节。)后续testl测试该偏移是否归零%edx。

jne被称为是因为它经常用于比较的上下文中,在ASM中通常只是减法。标志将根据差异设置;如果项目相等(因为x - x == 0),ZF将被设置。英特尔语法中也称为jnz;我不确定GNU是否也允许这样做。

总之,这三条指令转化为i <<= n; if (i != 0) goto L2;。这加上标签似乎做了for循环。

for (i = 1; i != 0; i <<= n) { result ^= i & x; } 

或者,更正确地(但实现相同的目标),do ... while循环。

i = 1; 
do { result ^= i & x; i <<= n; } while (i != 0); 
+0

谢谢!这非常有帮助。 – Catie 2010-10-24 13:31:33