汇编语言乘法问题

时间:2011-10-13 22:14:51

标签: assembly x86

所以我在为汇编代码运行作业时遇到问题。代码应该只是简单的乘法,但它不能使用imul函数或任何简单的东西,它必须使用移位。

汇编代码一定有问题,因为当我有emacs编译并运行main.c和multiply.s时,没有main.c实际调用乘法函数,它输出就好了。另一方面,当我调用乘法函数时,它强制它没有输出

输入我有:

我期待我的c文件,使用以下代码,在x和y上调用乘法,分别定义为34和47.

#include <stdio.h>

extern int multiply();
extern int x, y;

int main()
{
  x = 34;
  y = 47;
  printf("%d * %d = %d\n", x, y, multiply());
}

输出我预期: 我希望它运行乘法,这应该正确计算两者的乘积,然后打印出以下

34 * 47 = 1598

OUTPUT I GET:

无。当我从shell命令

运行它时,我收到一条消息
Shell command executed with no output

我的问题:

当我运行gcc -m32 main.c multiply.s

时,我一直收到错误消息
gcc -m32 multiply.s main.c
ld: warning: PIE disabled. Absolute addressing (perhaps -mdynamic-no-pic) not allowed in code signed PIE, but used in _multiply from /var/folders/ct/6_dmqq_11s9951v72wbcx06m0000gn/T//cc9DcDxr.o. To fix this warning, don't compile with -mdynamic-no-pic or link with -Wl,-no_pie

它生成一个a.out文件,当我从shell运行a.out文件时它给了我这个

(Shell Command succeeded with no output)

想法?

这是我的代码:

.globl _multiply
_multiply:
.data
    .globl _x
    .globl _y

_prod:  .long   0
_x: .long 0
_y: .long 0

pushl %ebp
movl %ebp,%esp


movl _x,%eax
movl _y,%edx
    movl $1,%ecx

LOOP:
cmpl $0,%eax
je DONE

and %eax,%ecx
cmp $0,%ecx
je CONTINUE
add %edx,_prod

CONTINUE:
shrl $1,%eax
shll $1,%edx
jmp LOOP

DONE:
    movl _prod,%eax
popl %ebp
ret

2 个答案:

答案 0 :(得分:2)

您获得的错误似乎与使用绝对地址有关。

避免这种情况的一种方法是在堆栈上接收您的输入(无论如何都是为此设置),并将结果返回到eax中。您应该能够使用大约4个寄存器将两个数字相乘,而根本没有其他存储。

另请注意,现在看起来它的堆栈使用情况不匹配。你有一个推动ebp的序言,但我没有看到任何东西在返回之前把它弹出来。

答案 1 :(得分:1)

首先,在改善你的问题+1上做得很好。

我能看到的一些事情:

_multiply:
.data
    .globl _x
    .globl _y

_prod:  .long   0
_x: .long 0
_y: .long 0
pushl %ebp

在这里,您要在函数中定义数据。这不是在函数开始时有指令,而是有一堆数据(当解释为指令时,它们的行为不会很好)。移动数据,例如(注意您要切换回代码的文本段):

.data
_x: .long 0
_y: .long 0
.text
_multiply:
pushl %ebp

此外:

movl %ebp,%esp

几乎肯定不是你想要的,因为你正在用%ebp的内容覆盖堆栈指针。将其更改为:

movl %esp,%ebp

(AT&amp; T语法可能令人困惑,您可以考虑使用.intel_syntax prefix,但这意味着更改所有代码。)

你的乘法函数也不起作用(你要覆盖你以后指望的值),但首先要做的事情是:)

PS:您还应该将return 0;放在main功能的末尾。