Проблемы умножения ассемблера - PullRequest
2 голосов
/ 14 октября 2011

Так что у меня проблема с выполнением домашнего задания для ассемблерного кода. Код должен просто выполнять простое умножение, но он не может использовать функцию 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

РЕЗУЛЬТАТ Я ПОЛУЧИЛ:

None. Когда я запускаю его из команды оболочки, я получаю сообщение о том, что

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, и когда я запускаю файл 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 ]

2 голосов
/ 14 октября 2011

Ошибка, которую вы получаете, похоже, связана с использованием абсолютного адреса.

Один из способов избежать этого - получение ваших входных данных в стеке (вы все равно настраиваете это),и вернуть результат в EAX.Вы должны быть в состоянии умножить два числа, используя около 4 регистров, без какого-либо другого хранилища.

Также обратите внимание, что сейчас похоже, что использование стека не соответствует.У вас есть пролог, который подталкивает ebp, но я не вижу ничего, что могло бы выкинуть его обратно до возвращения.

1 голос
/ 14 октября 2011

Прежде всего, отличная работа по улучшению вашего вопроса +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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...