【问题标题】:Why this asm code not doubling the value the pointer points为什么这个 asm 代码没有将指针指向的值加倍
【发布时间】:2015-05-08 18:26:07
【问题描述】:

我正在尝试将 c 代码与 asm 接口。 但它无法正常工作,我无法找到问题。

program.c

#include<stdio.h>
int *asm_multi(int *ptr);

int main()
{
  int i=10;
  int *p=&i;
  asm_multi(p);
  printf("%d\n",*p);
  return 0;
}

code.asm

.section .text
.global asm_multi
.type asm_multi,@function
asm_multi:
    pushl %ebp
    movl %esp,%ebp
    movl 8(%ebp),%eax
    movl %eax,%edx
    leal (%edx,%edx,1),%edx
    movl %edx,%eax
    movl %ebp,%esp
    popl %ebp
    ret

我正在创建最终的可执行文件

as code.asm -o code.o
gcc program.c code.o -o  output
./output

它打印的输出是:10 而我期望的是:20

代码有什么问题?不考虑程序的效率。我刚开始asm编程。

我在阅读了保存在this link 的一个更复杂的示例后创建了上面的代码。这非常有效。

【问题讨论】:

  • 无关,如果你刚开始 asm 编程并且了解 C,花时间倾注通过打开 asm 生成 (-S) 的 C 编译器发送的 simple 函数各种优化(包括没有)可以非常提供信息,我强烈鼓励它。该函数将是该技术的优秀候选者。
  • @WhozCraig:这真的很有帮助:)

标签: c assembly x86 att


【解决方案1】:

您应该尽快学会使用调试器。它不仅可以帮助您发现错误,还可以让您准确地看到 CPU 在每条指令上的执行情况,并可以将其与您的意图进行比较。

此外,请评论您的代码,尤其是在寻求帮助时,这样如果您自己无法做到,我们可以告诉您说明与您的意图不符的地方。

然后让我们评论您的代码:

asm_multi:
    pushl %ebp
    movl %esp,%ebp
    movl 8(%ebp),%eax        # fetch first argument, that is p into eax
    movl %eax,%edx           # edx = p too
    leal (%edx,%edx,1),%edx  # edx = eax + edx = 2 * p
    movl %edx,%eax           # eax = edx = 2 * p
    movl %ebp,%esp
    popl %ebp
    ret

如你所见,有两个问题:

  1. 您将指针翻倍,而不是它指向的值
  2. 您没有将它写回内存,只是在 eax 中返回它,然后被 C 代码忽略

一个可能的解决方法:

asm_multi:
    pushl %ebp
    movl %esp,%ebp
    movl 8(%ebp),%eax       # fetch p
    shll $1, (%eax)         # double *p by shifting 1 bit to the left
# alternatively
#   movl (%eax), %edx       # fetch *p
#   addl %edx, (%eax)       # add *p to *p, doubling it
    movl %ebp,%esp
    popl %ebp
    ret

【讨论】:

    猜你喜欢
    • 2021-07-07
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多