Чтение числа в регистр из стандартного ввода? Загрузка результата сканирования

В данный момент занят сборкой и столкнулся со следующей проблемой:

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

Я использовал следующий код, но я не понимаю его до конца. Обратите внимание на комментарии в коде.

Я знаю, что сейчас с номером абсолютно ничего не происходит, кроме того, что он был перемещен в eax. Что я действительно хочу знать, так это то, почему я должен использовать leal: почему и что он делает? и зачем мне возвращать eax обратно в стек?

.text
string1: .asciz "Please enter a number\n"
input: .asciz "%d" 

.global main
main:
       # Editor's note: this code is broken / unsafe; missing push %ebp here
  movl %esp, %ebp
  
  push $string1          # prompt string
  call printf            #print the string
           # no add $4, %esp here: 4 bytes still allocated on the stack

  leal -4(%ebp), %eax   # ????
  pushl %eax            # the thing you pushed in eax is now pushed on the stack?
  pushl $input          #the number 
  
  call scanf      
  
  popl %eax
  popl %eax       # the number that has been entered is now in eax
  
  call end
  
end:
  push $0
  call exit

person Gooey    schedule 04.06.2012    source источник
comment
Обратите внимание, что push %esp может заменить эти lea / push %eax, потому что ESP указывает на 4 байта, зарезервированных первым push $string1. Нет необходимости использовать указатель кадра, поэтому сломанный mov %esp, %ebp можно удалить. (Не работает, потому что вы не сохраняете/восстанавливаете EBP, но в стандартных соглашениях о вызовах он сохраняется).   -  person Peter Cordes    schedule 19.02.2021
comment
Кроме того, этот код небезопасен для современных систем, требующих выравнивания ESP по 16 байтам перед вызовом функций. (например, i386 System V ABI в Linux, но не в большинстве других ОС.)   -  person Peter Cordes    schedule 19.02.2021


Ответы (1)


Вы вызываете функции, поэтому вы передаете им параметры в стеке. Одно целое возвращается вам в eax, остальное через параметры указателя ввода-вывода, опять же, в стеке. Ознакомьтесь с соглашениями о вызовах x86.

Редактировать 0:

Инструкция leal сохраняет эффективный адрес некоторой временной переменной (где scanf помещает ваше целочисленное значение) в eax, затем вы передаете его scanf в стеке. Взгляните сюда: Какова цель инструкции LEA?< /а>

person Nikolai Fetissov    schedule 04.06.2012
comment
Хорошо, но что именно делает Леал? - person Gooey; 04.06.2012