如何解决如何在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
对齐是在call
和call
推送8字节(返回地址)之前完成的,因此应从函数指针中减去另外8字节以保持16字节对齐。
如果您想使用int**
作为第一个参数,请仅进行两次解除引用(内存访问)操作。
global bar
section .text:
bar:
mov rdx,8
call rsi
add rsp,8
ret
您可能想做的另一件事是
- 创建堆栈框架
- 将参数存储在堆栈内存中以供以后使用
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 举报,一经查实,本站将立刻删除。