我想了解 scanf 函数有 3 个关于它的问题。这是c文件:
#include <stdio.h>
#include <stdlib.h>
int main(){
int x;
printf("Enter X:\n");
scanf("%i",&x);
printf("You entered %d...\n",x);
return 0;
}
这是气体:
.text
.section .rodata
.LC0:
.string "Enter X:"
.LC1:
.string "%i"
.LC2:
.string "You entered %d...\n"
.text
.globl main
.type main, @function
main:
pushq %rbp #
movq %rsp, %rbp #,
subq $16, %rsp #,
# a.c:5: printf("Enter X:\n");
leaq .LC0(%rip), %rdi #,
call puts@PLT #
# a.c:6: scanf("%i",&x);
leaq -4(%rbp), %rax #, tmp90
movq %rax, %rsi # tmp90,
leaq .LC1(%rip), %rdi #,
movl $0, %eax #,
call __isoc99_scanf@PLT #
# a.c:7: printf("You entered %d...\n",x);
movl -4(%rbp), %eax # x, x.0_1
movl %eax, %esi # x.0_1,
leaq .LC2(%rip), %rdi #,
movl $0, %eax #,
call printf@PLT #
# a.c:8: return 0;
movl $0, %eax #, _6
# a.c:9: }
leave
ret
.size main, .-main
.ident "GCC: (Debian 8.3.0-6) 8.3.0"
.section .note.GNU-stack,"",@progbits
1)rsi应该取xint 的地址,但它在执行时从-4(%rbp)没有任何东西的地方取地址。因为x变量的初始化来自stdinas scanf等待输入来初始化变量。但是在-4(%rbp)指令的时候是leaq -4(%rbp), %rax什么?它看起来像是垃圾,而不是 的地址x,应该从 初始化哪个值stdin。
2)根据这个https://stackoverflow.com/questions/54165346/integer-describing-number-of-floating-point-arguments-in-xmm-registers-not-passe,这movl $0, %eax是零FP寄存器al,但是这是相同的约定printf。所以我的问题是,来自 glibc 或其他库的哪些函数应用了这种对流?(所以我必须%al在 printf、scanf、.... 中归零?)。我假设每个都有va_list或可变参数?
3) 气源中的堆栈金丝雀在哪里应该保护 scanf 缓冲区免于溢出?根据这个:scanf 如何与我的汇编代码交互,这应该设置金丝雀(在 masm 中):
0x080484c5 <+6>: mov eax,gs:0x14
0x080484cb <+12>: mov DWORD PTR [ebp-0xc],eax
0x080484ce <+15>: xor eax,eax
但是我在我的气体源中没有看到与此类似的东西,它也是从 gcc 输出的,它应该自己设置它(除非在我的源中不可见的 scanf 函数本身中有一些检查)。那么它在哪里呢?