Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.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
Arrays 通过scanf将值获取到数组中_Arrays_Assembly_X86_Scanf - Fatal编程技术网

Arrays 通过scanf将值获取到数组中

Arrays 通过scanf将值获取到数组中,arrays,assembly,x86,scanf,Arrays,Assembly,X86,Scanf,我不知道如何“扫描”数组中的值。我想,如果我计算每个索引的地址,将地址指向的值推送到堆栈上并调用scanf,它就会起作用。但是我得到了一个内存访问错误 那么,有没有办法做到这一点呢?由于某些原因,如果我使用%edi而不是%ecx作为索引,我无法判断它是否有效 我仍然不知道如何使用调试器,所以我在每次迭代中都打印出我的索引,看看哪里出了问题。问题是%ecx从未超过1,这使得过程陷入无限循环 然而,使用%edi时,增量工作得非常好 PS:出于好奇,我还尝试了其他寄存器,即%esi和%ebx。这也适用

我不知道如何“扫描”数组中的值。我想,如果我计算每个索引的地址,将地址指向的值推送到堆栈上并调用scanf,它就会起作用。但是我得到了一个内存访问错误


那么,有没有办法做到这一点呢?

由于某些原因,如果我使用%edi而不是%ecx作为索引,我无法判断它是否有效

我仍然不知道如何使用调试器,所以我在每次迭代中都打印出我的索引,看看哪里出了问题。问题是%ecx从未超过1,这使得过程陷入无限循环

然而,使用%edi时,增量工作得非常好

PS:出于好奇,我还尝试了其他寄存器,即%esi和%ebx。这也适用于他们。如果我能找到原因,我会回到这篇文章

编辑:好吧,这个错误很愚蠢。我没有遵守通话惯例

所以
scanf
,就像
printf
,显然改变了寄存器值。按照惯例,
%eax
%ecx
%edx
是调用方保存,而
%ebx
%edi
%esi
是调用方保存。 因为我作为调用者在调用
scanf
之前没有保存
%ecx
,所以我在
%ecx
中得到了一个不需要的值。 它适用于
%edi
%esi
%ebx
,因为它们是被调用方保存的,因此保证不会被调用函数更改。因此,如果我尝试使用
%eax
%edx
替代,它很可能也不会起作用

是的,如果我在调用scanf之前在堆栈上按下
%ecx
,它会工作得非常好

编辑2: 哦,通过使自己成为一个全局变量,扫描一个数字,并将该数字移动到所需的索引中,解决了访问问题:

.data
arr: .long 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
arr_size: .long 10
in: .string "%d"

.text
.global main
main:

#scanf
movl $0, %ecx # index i
scanloop:
  cmpl arr_size, %ecx 
  je endscan # if ecx == 10 -> break
  leal arr(, %ecx, 4), %eax # load the address of arr[i] into eax
  pushl (%eax) # push the value that is being pointed at onto the stack
  pushl $in
  call scanf
  addl $8, %esp 
  incl %ecx
  jmp scanloop
#endscanf

endscan:
#...
.data
num: .long 0
#...
scanloop:
  cmpl arr_size, %ecx 
  je endscan # if ecx == 10 -> break

  pushl %ecx #caller-save
  pushl $num
  pushl $in
  call scanf
  addl $8, %esp
  popl %ecx #restore
  movl num, %eax #in order to avoid two memory arguments to movl

  leal arr(, %ecx, 4), %edx #calculate address of index
  movl %eax, (%edx) #store num in that index

  incl %ecx
  jmp scanloop
#endscanf
#...