【问题标题】:Assembly set address to point to an address程序集设置地址指向一个地址
【发布时间】:2013-05-16 01:53:54
【问题描述】:

我正在尝试在程序集中构建一个链表(不要问为什么),链表必须在我构建的堆栈中。 我在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

我该怎么做? 谢谢!

【问题讨论】:

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


    【解决方案1】:

    我建议你确保malloc 成功(即检查它是否返回一个非空指针)。


    另外,这两行:

    push  STKSZ*4
    push  size_of_struct
    

    最好写成:

    push  strict dword STKSZ*4
    push  strict dword size_of_struct
    

    为了确保它实际推送的是一个双字而不是一个字节(这实际上意味着推送一个字)。


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

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

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

    【讨论】:

      【解决方案2】:
      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

      【讨论】:

      • 如果最后一个超级安全的不起作用,恐怕我没有更多的想法。对不起
      【解决方案3】:

      这在 DOS 中不起作用

      mov [cx],ax

      但这会

      mov [bp],ax

      用寄存器指向时可能有一个规则

      【讨论】:

      • 您可能需要在将 ebp 用作指针之前推送/存储它,然后使用 pop 或 mov 将其恢复为原始值。取决于你的程序。
      • -1 用于提出与问题无关的实模式寻址模式限制,并用于发布同一问题的多个答案而不是编辑原始答案。
      猜你喜欢
      • 1970-01-01
      • 2020-05-17
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多