开发者

Assembly language multiplication problems

So i have a problem running a homework assignment for assembly code. The code is supposed to just do simple multiplication but it can't use the imul function or anything simple like that, it has to use shifts.

There must be something wrong with the assembly code because when I have emacs compile and run main.c and multiply.s, without having main.c actually call the multiply function, it outputs just fine. On the other hand, when I have it call the multiply function, it forces it not to have output

INPUT I HAVE:

I'm expecting my c file, with the following code, to call multiply on x and y, which are defined as 34 and 47 respectively.

#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 I EXPECT: I expect it to run multiply, which should correctly calculate the product of the two, and then print out the following

34 * 47 = 1598

OUTPUT I GET:

None. I get a message when I run it from the shell command saying

Shell command executed with no output

MY PROBLEM:

I keep getting an error when I run gcc -m32 main.c multiply.s that says

gcc -m32 multiply.s main.c
ld: warning: PIE dis开发者_如何学Goabled. 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

It generates an a.out file, and when I run the a.out file from the shell it gives me this

(Shell Command succeeded with no output)

Ideas?

Here's my code:

.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


The error you're getting seems to be related to using an absolute address.

One way to avoid that would be to receive your inputs on the stack (you're setting up for that anyway), and return the result in eax. You should be able to multiply two numbers using around 4 registers, with no other storage at all.

Also note that right now it looks like its stack usage is mismatched. You have a prolog that pushes ebp, but I don't see anything to pop it back off before the return.


First off, great job on improving your question +1 for that.

A few things I can see:

_multiply:
.data
    .globl _x
    .globl _y

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

Here you're defining data in your function. That is instead of having instructions at the start of your function you have a bunch of data (which, when interpreted as instructions will not behave nicely). Move the data away, something like (notice that you want to switch back to the text segment for the code):

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

Also:

movl %ebp,%esp

Is almost certainly not what you want, as you're moving overwriting the stack pointer with contents of %ebp. Change that to:

movl %esp,%ebp

(AT&T syntax can be confusing, you could consider using .intel_syntax prefix but that means changing all of the code).

Your multiplication function also won't work (you're overwriting values you're counting on later), but first things first :)

PS: You should also put return 0; at the end of your main function.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜