汇编集地址指向地址

时间:2013-05-21 10:19:13

标签: assembly linked-list segmentation-fault nasm memory-address

我正在尝试在汇编中构建链表(不要问为什么),链表必须在我构建的堆栈中。 我在ubuntu上使用带有intel 80x86的nasm 这是链表:

size_i:
struc node
  data: resb  1
  next: resb  4
endstruc
size_of_struct: equ $-size_i

这是堆栈:

  create_stack:
  push  STKSZ*4
  call  malloc
  add       esp,4 ;correct the push
  mov   dword[my_stack],eax
  ret

现在,我们从用户读取一个数字,每个字节都发送到列表中的另一个节点。 这就是我尝试创建新列表的方式:

create_new_list:
  push  size_of_struct
  call  malloc ;now eax has pointer to location
  add       esp,4 ;correct the push
  mov   edx,0
  mov   dl,byte[ebx] ;dl is the data of current number (current digit)
  mov   byte[eax+data],dl ;set the data
  mov   dword[eax+next],0 ;set next to be null  
  ;BUILD THE FIRST NODE IN EAX

  push  edx
  push  ecx
  push  eax
  mov   eax,0
  mov   ecx,dword[my_stack]
  mov   dword[curr_stack_pointer],ecx
  mov   ecx,0
  mov   cl,byte[counter]
  mov   al,4
  mul   cl
  add   dword[curr_stack_pointer],eax
  ;DWORD[CURR_STACK_POINTER] HAS THE POINTER TO HEAD OF LIST
  pop   eax
  mov   ecx,dword[curr_stack_pointer]

  mov   [ecx],eax ;THIS IS THE PROBLEMATIC LINE. HERE I AM TRYING TO 
                      ;MOV THE ADDRESS INSIDE EAX TO THE LOCATION OF ECX
                      ;THIS WAY I WILL HAVE IN THE CURRENT ARRAY BLOCK THE ADDRESS
                      ;OF THE HEAD OF THE LIST. BUT IT IS NOT WORKING, I GET A 
                      ;SEGMENTATION ERROR
  pop   ecx
  pop   edx

  ret

我该怎么做? 谢谢!

3 个答案:

答案 0 :(得分:0)

push ebp
mov   ebp,dword[curr_stack_pointer]
mov   [ebp],eax
pop ebp

如果仍然失败那么

mov   ebp,dword[curr_stack_pointer-4]

可能会很幸运

或尝试

mov   ecx,dword[curr_stack_pointer]
mov   ebp,ecx
mov   [ebp],eax

ebp可能不接受dword [curr_stack_pointer-4]作为直接MOV

答案 1 :(得分:0)

我建议您确保malloc成功(即检查它是否返回非NULL指针)。


另外,这两行:

push  STKSZ*4
push  size_of_struct

最好写成:

push  strict dword STKSZ*4
push  strict dword size_of_struct

确保它实际推送一个dword而不是一个字节(这实际上意味着推送一个单词)。


乘以4有点过于复杂。它可以写成:

mov eax,dword [my_stack]
movzx ecx,byte [counter]
lea ecx,[eax+ecx*4]

并确保counter在有效范围(0 <= counter < STKSZ)内,这样您就不会尝试在&#34;堆栈的边界之外进行读/写操作。

答案 2 :(得分:-1)

这在DOS中不起作用

mov [cx],ax

但这将

mov [bp],ax

当用寄存器指向

时可能有一条规则