I am trying to understand scanf function a have 3 question regarding it.
this is c
file:
#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;
}
and here is gas:
.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)
The rsi
should take address of x
int, but it takes the address from -4(%rbp)
, where there is nothing, in time of execution. Because the initialization of x
variable comes from the stdin
as scanf waits for input to init the variable. But the what is in -4(%rbp)
in the time of instruction leaq -4(%rbp), %rax
? It looks like garbage, not address of x
, which value should be initialized from stdin
.
2)according to this https://stackoverflow.com/questions/54165346/integer-describing-number-of-floating-point-arguments-in-xmm-registers-not-passe, the movl $0, %eax
is to zero FP registers in al
, but that is the same convention for printf
. So my question is, to which functions from glibc or other libraries apply this convetion? (So I have to zero %al
in printf, scanf, ....?). I assume to every, that has va_list
or variable argument?
3) where in the gas source is stack canary in that should protect scanf buffer from overflow? according to this: How does scanf interact with my code in assembly, this should set canary (in masm):
0x080484c5 <+6>: mov eax,gs:0x14
0x080484cb <+12>: mov DWORD PTR [ebp-0xc],eax
0x080484ce <+15>: xor eax,eax
But I see nothing similar to this in my gas source, which is also output from gcc, which should set it by itself (unless there is some checking in the the scanf function itself which is not visible in my source). So where is it?