This was too long for a comment, but you can see why this is happening here:
0x080484a7 <+58>: call 0x8048360 <__isoc99_scanf@plt>
0x080484ac <+63>: mov 0x2c(%esp),%ebx
0x080484b0 <+67>: mov 0x28(%esp),%ecx
0x080484b4 <+71>: mov 0x24(%esp),%edx
0x080484b8 <+75>: mov 0x20(%esp),%eax
0x080484bc <+79>: mov %ebx,0x10(%esp)
...
End of assembler dump.
(gdb) break *main+79
Breakpoint 4 at 0x80484bc
(gdb) r
Starting program: /root/test/testcode
04/21
Breakpoint 4, 0x080484bc in main ()
(gdb) i r
eax 0x4 4
ecx 0x80484fb 134513915
edx 0xb7fff000 -1207963648
ebx 0xb7fcc000 -1208172544
esp 0xbffff720 0xbffff720
ebp 0xbffff758 0xbffff758
esi 0x0 0
edi 0x0 0
eip 0x80484bc 0x80484bc <main+79>
eflags 0x286 [ PF SF IF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
(gdb) c
Continuing.
4-1207963648134513915-1208172544
Here's whats happening:
mov 0x2c(%esp),%ebx
mov 0x28(%esp),%ecx
mov 0x24(%esp),%edx
mov 0x20(%esp),%eax
These four mov
statements are preparation for the printf()
call. Each %d
corresponds to one of the registers: eax ebx ecx edx
You can see that it is moving four bytes into each register. This is the reason you see gibberish. Each %d
getting printed is expecting a 4-byte integer.
I set a breakpoint after all four of those mov
statements, so lets look at what they contain:
eax 0x4 4
ecx 0x80484fb 134513915
edx 0xb7fff000 -1207963648
ebx 0xb7fcc000 -1208172544
This doesn't look right at all, but it does indeed correspond to what's on the stack:
0xbffff740: 0x00000004 0xb7fff000 0x080484fb 0xb7fcc000
These are the four values that wind up in the registers.
The first one is actually your 04
combined. It interpreted 04
as being within the bounds of %d
, which is a 4-byte integer on my machine.
Since you tried to grab four %d
's, the program continues as it should and prints out four %d
s. In other words, it prints out four 4-byte integers.
The reason this is happening is what Jonathan Leffler explained: scanf is gobbling up the 04
into the first %d
, then breaking on the /
You still have a printf() of %d%d%d%d
though, so the program dutifully prints out the remaining 4-byte decimal values. Since scanf
failed, the remaining 3 %d
s contain whatever happened to be on the stack.