Assembly “呼叫”是如何工作的
我很确定命令行上的输入参数应该是字符串,但是当我调用uu isoc99_sscanf时,eax寄存器的值为0。我真的不知道call u isoc99_sscanf应该如何工作,但我知道堆栈指针的排序如下: .LC1 | v eax .LC1为输入:%s,调用前的eax为33,并在内存中保存字符串。在任何情况下,调用uu isoc99_sscanf何时会导致1Assembly “呼叫”是如何工作的,assembly,x86,Assembly,X86,我很确定命令行上的输入参数应该是字符串,但是当我调用uu isoc99_sscanf时,eax寄存器的值为0。我真的不知道call u isoc99_sscanf应该如何工作,但我知道堆栈指针的排序如下: .LC1 | v eax .LC1为输入:%s,调用前的eax为33,并在内存中保存字符串。在任何情况下,调用uu isoc99_sscanf何时会导致1 .code32 .file "mystery.c" .text .LCO: .string "Incorrect number o
.code32
.file "mystery.c"
.text
.LCO:
.string "Incorrect number of command line arguments given"
.LC1:
.string "Input:%s"
.align 4
.LC2:
.string "Incorrect format for command line argument"
.LC3:
.string "Output: \"%s\"\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
cmpl $2, 8(%ebp)
je .L18
movl $.LC0, (%esp)
call puts
movl $1, %eax
jmp .L19
.L18:
movl 12(%ebp), %eax
addl $4, %eax
movl (%eax), %eax
movl %eax, (%esp)
call strlen
movl %eax, %edx
movl %edx, %eax
sall $2, %eax
addl %edx, %eax
movl %eax, (%esp)
call malloc
movl %eax, 28(%esp)
movl $.LC1, %edx
movl 12(%ebp), %eax
addl $4, %eax
movl (%eax), %eax
movl 28(%esp), %ecx
movl %ecx, 8(%esp)
movl %edx, 4(%esp)
movl %eax, (%esp)
call __isoc99_sscanf
cmpl $1, %eax
je .L20
movl $.LC2, (%esp)
call puts
movl $1, %eax
jmp .L19
.L20:
movl 28(%esp), %eax
movl %eax, (%esp)
call foo
movl $.LC3, %eax
movl 28(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
movl 28(%esp), %eax
movl %eax, (%esp)
call free
jmp .L17
.L19:
.L17:
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-4)"
.section .note.GNU-stack,"",@progbits
我认为这有助于:
man scanf:
These functions return the number of input items successfully matched
and assigned, which can be fewer than provided for, or even zero in the
event of an early matching failure.
基本上,它返回您刚刚输入计算机的输入总数。如果在14中放入两个数字,则会将%rax设置为2 这是32位代码,因此调用前的EAX没有意义。在x86-64系统V ABI中,al=在XMM寄存器中传递的FP arg数。对于scanf,它将始终为0,因为您传递的是指针,而不是值,除非调用方通过传递一些FP值而具有未定义的行为。请确保您在调用后通过跨过/越过EAX来查看EAX,而不仅仅是在到达调用时。问题中的代码使用的格式字符串为.LC1:。字符串输入:%s,因此,如果输入EAX/RAX为1,则输入缓冲区的4部分将保持未转换状态。sscanf返回int,所以从技术上来说,假设它正确地零扩展到RAX是不安全的;RAX的上4个字节可能包含垃圾。但这是32位代码,所以这一点毫无意义。