c - x86汇编代码混淆

标签 c assembly x86 intel

我们刚刚开始关于汇编的话题,我在这个问题上停留了最长的时间。鉴于以下情况,我必须将汇编代码转换为 C 代码:

C 代码:

int foo(int *a, int n, int val) {
    int i;
    for (i = _________; ____________________________ ; i =___________) {
        ;
    }
    return i;
}

程序集:

// what I've gathered so far
foo()
:
foo:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp),%ecx  // ecx: a
movl 16(%ebp),%edx  // edx: val
movl 12(%ebp),%eax  // eax: n
decl %eax  // n = n--
js .L3  // if n < 0 goto done
.L7:  // loop
cmpl %edx,(%ecx,%eax,4)  // I don't understand how you would compute the
// address for (%ecx,%eax,4) I know it would be %ecx + %eax*4 = %ecx + eax << 2
jne .L3  // if (%ecx, %eax, 4) != val goto done (?)
decl %eax  // n = n--
jns .L7  // if (n >= 0) jump to loop
.L3:  // done
movl %ebp,%esp
popl %ebp
ret

我不知道如何弄清楚我正在初始化什么以及循环体是什么。我假设 i = n 因为 n 作为更新。似乎有两个条件,一个是 n > 0,另一个是 cmpl 行。如果我对代码的理解不正确,请纠正我,非常感谢有关此问题的任何线索。

最佳答案

我本可以做一些偏离 1 的错误,但基本上是这样的:

int foo(int *a, int n, int val) {
    int i;
    for (i = n - 1; i >= 0 && a[i] == val; i = i - 1) {
        ;
    }
    return i;
}

i%eax登记;它从 n - 1 开始循环到 0。 cmpl索引访问 (%ecx,%eax,4)以字节为单位寻址 - 这相当于 a[i] , 大小为 int在 ia32 上是 4 个字节。将因此寻址的 4 个字节与 val 进行比较.

%eax隐式返回。

另请注意,js表示 < 0 , 和 jns <强> >= 0 .


另一种写法:

    i = n;
    i --;               //  decl %eax
    if (i < 0) {
        goto L3;        //  js .L3
    }
L7:
    if (a[i] != val)    // cmpl %edx,(%ecx,%eax,4)
        goto L3;        // jne .L3

    i --;               // decl %eax
    if (i >= 0)
        goto L7;        // jns .L7

L3:
    return i;

关于c - x86汇编代码混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29186160/

相关文章:

c - 使用AVX512或AVX2最快的方法来计算所有打包的32位整数的和

c - C编程AT89C51中的局部变量

c - 'asmlinkage' 修饰符是什么意思?

c - 有什么方法可以检查用 ObRegisterCallbacks 注册的回调是否仍然有效?

assembly - x86 操作码编码 : sib byte

c++ - 二叉树的最小高度?

assembly - ARM 汇编 - 写入内存 - 段错误

assembly - 如何延迟 avr 微 Controller 的组装?

caching - 如何正确使用预取指令?

c - 如何在 C 程序中禁用操作系统 (Ubuntu) 缓存