将汇编语言翻译成C语言

3

我是一名助手,将为您翻译以下关于IT技术的内容。请注意,该问题要求将给定的IA32汇编代码转换为C语言等效代码。以下是需要翻译的内容:

我现在正在审查一份练习期中考试。问题提供了一段汇编代码(IA32),并指示编写其C语言等效代码。只是想确保我正确地完成了它。谢谢!

给出的汇编程序:

.global _someOperation
_someOperation:
    pushl %ebp
    movl %esp, %ebp
    movl 8(%ebp), %ebx
    movl 12(%ebp), %edx
    decl %edx
    xorl %esi, %esi
    movl (%ebx, %esi, 4), %eax
continue:
    incl %esi
    cmpl (%ebx, %esi, 4), %eax
    jl thelabel
    movl (%ebx, %esi, 4), %eax
thelabel:
    cmp %esi, %edx
    jne continue
    movl %ebp, %esp
    popl %ebp
    ret

这是我编写的代码:
void someOperation(int *num, int count)  //Given
{
    int k; //Given
    count--;
    int i = 0;
    k = num[i];
    i++;
    while(count != i)
    {
        if(k >= num[i]
            k = num[i];
        i++;
    }
    return (k);
 }

1
尝试使用gcc -m32 -S file.c进行编译,看看会得到什么结果。你会注意到你的代码有一个语法错误,并且一个void函数返回了一个值。 - user66363
你说得对。汇编代码中有%eax,所以我认为应该返回一个值,但是“void someOperation”是给我们的C代码的开头。那么就不需要返回值了吧? - Martyax
1
是的,删除return语句,使用do-while循环。(如果传入的计数为1,则汇编代码将出错。您的函数也应该如此。) - user66363
1个回答

2

我认为这很接近正确,虽然在ASM中增量只在循环开始时进行,并且第一次不检查条件。考虑使用DO...WHILE代替。

另外,你的赋值是错误的。MOV指令将从第二个参数复制到第一个参数。你在C代码中相反了。


啊!我没想到那个。谢谢! - Martyax
2
Garr,我认为参数顺序取决于AT&T与Intel语法。这段代码看起来像是AT&T语法。但是该函数中肯定有很多问题。如果count为0或1,则它很容易无限循环。如果count是要检查的数量,则似乎检查了一个元素过少。此外,它会破坏ebx和esi,这些寄存器应该被保留。 - JS1
你可能对操作数的顺序是正确的,但我不同意应该保留 ESI 和 EBX。这通常不是这样的。由于inc在test之前执行,因此它检查了正确数量的元素,因为它在count == i时进行了检查。 - Garr Godfrey
但是肯定的是,如果计数小于2,你会遇到问题。 - Garr Godfrey
你说得对,它确实检查了正确数量的元素。只是让我感到困惑的是它看起来很不对。我认为ebx和esi应该被保留的原因是因为我习惯于cdecl调用约定。x86调用约定的维基百科文章。你习惯哪种调用约定? - JS1
据我所知,大多数编译器都需要保留 ESI 和 EBX 寄存器。可用的寄存器是 EAX、EXC 和 EDX。这是 AT&T 语法,因此最左边的操作数移动到最右边。 - Rudy Velthuis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接