Попытка сохранить два числа с помощью scanf, но программа вылетает - PullRequest
3 голосов
/ 21 декабря 2011

С учетом следующего кода:

.section .rodata

input_format1:  .string  "%d%d"
output_format1: .string  "Yes. %d is a power of %d\n"
output_format2: .string  "No. %d is not a power of %d\n"

.section .text
.globl  main
    .type main, @function
main:
        pushl   %ebp
        movl    %esp,   %ebp

        addl    $-8 ,%esp       # moving down the stack
        pushl   %esp
        pushl   4(%esp)
        pushl   $input_format1
        call    scanf           # call scanf to get a number from the user
        addl    $12,%esp
        movl    (%esp),%ebx     # store the actual number
        movl    4(%esp),%ecx


.loop:


        #return from printf:
        movl    %ebp,%esp
        popl    %ebp
        ret

После того, как программа достигает scanf и я нажимаю 1-е число, она вылетает. Что я делаю не так?

Спасибо Рон

1 Ответ

2 голосов
/ 21 декабря 2011

Проблема в:

pushl   4(%esp)

Это помещает значение в стек, а не адрес такой переменной.Сравните это с предыдущей правильной инструкцией pushl %esp.Этот действительно выдвигает адрес.

Вам нужно pushl %esp+4, но это невозможно сделать только одной инструкцией AFAIK.Вместо этого сделайте что-то вроде:

lea 4(%esp), %eax
push %eax

ОБНОВЛЕНИЕ:

Другая ваша проблема в том, что каждый раз, когда вы выполняете push% esp, уменьшается, поэтому вычисление правильного адреса для ваших локальных переменных является грязным.Это одна из причин иметь фрейм стека, и у вас есть один!Поэтому используйте% ebp для ссылки на ваши локальные переменные, но с отрицательным смещением:

    pushl   %ebp
    movl    %esp,   %ebp
    addl    $-8 ,%esp       # moving down the stack
    lea     -4(%ebp), %eax
    pushl   %eax
    lea     -8(%ebp), %eax
    pushl   %eax
    pushl   $input_format1
    call    scanf           # call scanf to get a number from the user
    addl    $12,%esp
    movl    -8(%ebp),%ebx     # store the actual number
    movl    -4(%ebp),%ecx
...