Assembly 从标准输入到寄存器中读取一个数字?加载扫描结果

Assembly 从标准输入到寄存器中读取一个数字?加载扫描结果,assembly,x86,att,Assembly,X86,Att,我当前正忙于组装,遇到以下问题: 我正在尝试获取一个已输入eax寄存器的数字。首先我给出一个字符串,要求输入,然后有人必须输入一个数字 我使用了下面的代码,但我不完全理解它。请注意代码中的注释 我知道现在这个数字完全没有任何变化,除了它已经被移动到eax中。我想知道的是为什么我必须使用leal:为什么和它有什么作用?为什么我需要将eax推回到堆栈上 .text string1: .asciz "Please enter a number\n" input: .asciz &q

我当前正忙于组装,遇到以下问题:

我正在尝试获取一个已输入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

您正在调用函数,因此在堆栈上向它们传递参数。在
eax
中返回一个整数,其余的通过堆栈上的输入输出指针参数返回。退房

编辑0:
leal
指令将某个临时变量的有效地址(即
scanf
将整数值放入
eax
中)存储在堆栈上,然后将其传递给
scanf
。看看这里:

好的,但是leal到底做了什么?请注意,
push%esp
可以替换
lea
/
push%eax
,因为esp指向第一个
push$string1
保留的4个字节。根本不需要使用帧指针,因此可以删除损坏的
mov%esp,%ebp
。(由于没有保存/恢复EBP而中断,但在标准调用约定中,它保留了调用)。此外,对于在调用函数之前需要16字节ESP对齐的现代系统,此代码也不安全。(例如Linux上的i386 System V ABI,但不是大多数其他操作系统。)