微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在ASMx64中多次取消对指针的引用?

如何解决如何在ASMx64中多次取消对指针的引用?

所有内容都在标题中,我有一个int **作为我的函数参数,我想用汇编显示该int,所以我要做的是:

global bar

section .text:
bar:
  mov  rdx,[rdi]
  mov  rdi,[rdx]
  mov  rdx,[rdx]
  call rsi
  ret

我的C代码

#include <stdio.h>

void  bar(int **i,void (*f)());  //assembly function prototype

void  foo(int i)
{
  printf("%d\n",i);
}

int   main(void)
{
  int i = 3;
  int *ptr = &i;

  bar(&ptr,&foo);
  return (0);
}

它出现段错误并在lldb的foo上说“无效地址”,所以我认为这是因为我没有正确引用正确的方法,所以我被卡住了,因为我需要为更大的功能执行此操作。感谢您的帮助。

解决方法

让我跟踪汇编代码:

global bar

section .text:
bar:
  mov  rdx,[rdi] // rdi = &ptr,rdx = *&ptr = ptr
  mov  rdi,[rdx] // rdx = ptr,rdi = *ptr = i
  mov  rdx,[rdi] // rdi = i,rdx = *i = (invalid)
  mov  rdi,[rdx]
  call rsi
  ret

这实际上建议您必须传递int****而不是int**作为第一个参数,因为您要进行4次取消引用。

它将是这样的:

#include <stdio.h>

void  bar(int ****i,void (*f)());  //assembly function prototype

void  foo(int i)
{
  printf("%d\n",i);
}

int   main(void)
{
  int i = 3;
  int *ptr = &i;
  int **pptr = &ptr;
  int ***ppptr = &pptr;

  bar(&ppptr,&foo);
  return (0);
}

在x86-64中的函数调用上,堆栈指针也应对齐16字节,因此汇编功能bar应该是(例如):

global bar

section .text:
bar:
  mov  rdx,[rdi]
  mov  rdi,[rdx]
  mov  rdx,[rdx]
  sub  rsp,8 // adjust stack pointer
  call rsi
  add  rsp,8 // restore stack pointer
  ret

对齐是在callcall推送8字节(返回地址)之前完成的,因此应从函数指针中减去另外8字节以保持16字节对齐。

如果您想使用int**作为第一个参数,请仅进行两次解除引用(内存访问)操作。

global bar

section .text:
bar:
  mov  rdx,8
  call rsi
  add  rsp,8
  ret

您可能想做的另一件事是

  1. 创建堆栈框架
  2. 将参数存储在堆栈内存中以供以后使用
global bar

section .text:
bar:
  push rbp // create stack frame
  mov  rbp,rsp
  sub  rsp,16 // create region for local variables (note 16-byte alignment)
  mov  [rbp-8],rdi // save the argument to the memory
  mov  rdx,[rdx]
  mov  rdi,[rbp-8] // restore the argument from the memory
  mov  rdx,[rdx]
  call rsi
  leave // destruct stack frame
  ret
,

我想你可能想要这个:

bar:
   mov   rax,[rdi]
   mov   edi,[rax]
   call  rsi
   ret

void bar(int **i,void (*f)())原型相匹配的

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。