从标准输入将数字读入寄存器?加载 scanf 结果
Posted
技术标签:
【中文标题】从标准输入将数字读入寄存器?加载 scanf 结果【英文标题】:Reading a number into a register from stdin? Loading a scanf result 【发布时间】:2012-06-04 12:30:58 【问题描述】:我目前正忙于组装,遇到了以下问题:
我正在尝试获取已输入 eax 寄存器的数字。首先我提出一个要求输入的字符串,然后有人必须输入一个数字。
我使用了以下代码,但我并没有完全理解它。请注意代码中的 cmets。
我知道这个数字现在绝对没有任何反应,除了它已被移入 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
【问题讨论】:
请注意push %esp
可以替换 lea
/ push %eax
因为 ESP 指向第一个 push $string1
保留的 4 个字节。根本不需要使用帧指针,因此可以删除损坏的mov %esp, %ebp
。 (因为您没有保存/恢复 EBP 而损坏,但在标准调用约定中它是保留调用的)。
此外,对于在调用函数之前需要 16 字节 ESP 对齐的现代系统,此代码也不安全。 (例如 Linux 上的 i386 System V ABI,但不是大多数其他操作系统。)
【参考方案1】:
您正在调用函数,因此您在堆栈上将参数传递给它们。一个整数在eax
中返回给您,其余的是通过输入-输出指针参数再次在堆栈上。查看x86 calling conventions。
编辑0:
leal
指令将某个临时变量(scanf
放置整数值的位置)的有效地址存储到eax
,然后将其传递给堆栈上的scanf
。看这里:What's the purpose of the LEA instruction?
【讨论】:
好的,但是 leal 到底是做什么的呢?以上是关于从标准输入将数字读入寄存器?加载 scanf 结果的主要内容,如果未能解决你的问题,请参考以下文章