2011-10-13 102 views
2

所以我要运行汇编代码家庭作业的问题。该代码应该只是简单的乘法,但它不能使用imul函数或任何简单的那样,它必须使用移位。汇编语言乘法问题

一定有什么错误的汇编代码,因为当我有emacs的编译和运行的main.c和multiply.s,而不必main.c中实际调用多重功能,它输出就好了。在另一方面,当我把它称之为多重功能,它迫使它不具有输出

INPUT我有:

我期待我的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()); 
} 

OUTPUT我期望: 我希望它乘法运行,应该正确地计算两者的产品,然后打印出以下

34 * 47 = 1598 

输出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 

它产生的一个。 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 
+0

您使用的是什么操作系统/系统/汇编程序? –

+0

我正在使用一个mac,我使用的是AT&T语法 – NONE

回答

2

你得到的错误似乎与使用绝对地址。避免

一种方式是到堆栈(你正在设置为该反正)在收到您的输入,并在EAX返回结果。您应该能够使用大约4个寄存器乘以两个数字,而根本没有其他存储。

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

+0

我修改了我的代码,就像你说的那样。仍然得到相同的错误。我现在在返回之前也会弹出ebp。仍然不起作用。 – NONE

+0

此外,我认为这可能是狮子OSX的问题。我跑过这篇文章: http://caml.inria.fr/mantis/bug_view_advanced_pa​​ge.php?bug_id=5365 这似乎表明警告是由于某种原因不正确。 – NONE

+0

另外,我可以使用哪四个寄存器?我的教授告诉我不要使用ebx,因为它会导致问题。 – NONE

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 & T语法可能会造成混淆,你可以考虑使用.intel_syntax prefix但是这意味着改变所有的代码)。

你的乘法功能也将无法正常工作第一(你覆盖你以后指望值),但第一件事情:)

PS:你也应该把return 0;main函数结束。

+0

完美!解决了问题!真正的关键是movl%esp,%ebp。在你回答之前,我实际上已经明白了这一点,并且我终于得到了一些结果。之后,对于实际的算法很容易解决。再次感谢!!! – NONE

+0

@NONE:很高兴你的工作,但你不应该删除你的问题,因为每个人在未来看到它会感到困惑。我已回滚您的修改。 – user786653