Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly “呼叫”是如何工作的_Assembly_X86 - Fatal编程技术网

Assembly “呼叫”是如何工作的

Assembly “呼叫”是如何工作的,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

我很确定命令行上的输入参数应该是字符串,但是当我调用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 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位代码,所以这一点毫无意义。