【问题标题】:Using printf while calling ASM from C从 C 调用 ASM 时使用 printf
【发布时间】:2018-07-04 15:51:56
【问题描述】:

我想从 C (GCC) 调用 ASM (MASM)。简单的! 现在我希望我的 asm 函数能够使用数据并调用 printf() 等函数。

我遇到了两个问题:数据部分和对 printf() 的调用

我已经阅读了互联网上的示例,这些示例与我的完全一样,但似乎并没有失败。欢迎任何帮助。

test.c:

#include <stdio.h>
int64_t asmfunc();
int main() {
asmfunc());
return 0;
}

test.asm

global  asmfunc
section .data
msg: db "a very inspired message!",10,0
section .text
extern printf
asmfunc:
mov edi,msg
xor eax,eax
call printf
ret 

编译:

nasm -felf64 maxofthree.asm 
gcc callmaxofthree.c maxofthree.o 

结果:

/usr/bin/ld: maxofthree.o: relocation R_X86_64_32 against `.data' can not  
be used when making a shared object; recompile with -fPIC

如果我只是离开 printf 调用,删除 .data 部分和“mov edi,msg”,我会得到

 /usr/bin/ld: maxofthree.o: relocation R_X86_64_PC32 against symbol 
`printf@@GLIBC_2.2.5' can not be used when making a shared object; 
recompile with -fPIC

感谢各位程序员

【问题讨论】:

  • 使用call printf wrt ..plt。某些版本的 gcc 默认创建与位置无关的代码。 gcc -no-pie 也可以。另见this answer。您可能还需要将 mov edi,msg 替换为 lea rdi, [rel msg]
  • call print wrt ..plt 不幸地给了我一个分段错误,无论如何感谢您的提示,我们可能会越来越近
  • 您还需要对齐堆栈。
  • 您的解决方案很好,解决了问题。谢谢。由于我的菜鸟,我忘记了 edi 已成为 rdi,这要归功于 asm32/64。甚至不需要对齐堆栈。再次感谢
  • @Mist 请不要在您的帖子标题中添加“已解决”。相反,为您自己的问题添加一个答案,说明您是如何解决它的。

标签: assembly compilation


【解决方案1】:

解决方案:

test.asm

global  asmfunc
section .data
msg: db "a very inspired message!",10,0
section .text
extern printf
asmfunc:
lea rdi,[rel msg]
xor rax,rax
call printf wrt ..plt
ret 

感谢您的帮助

【讨论】:

  • 这会使 printf 的堆栈错位,并且可能会在某些未来版本的 libc (like glibc scanf currently does) 上出现段错误。使用 jmp printf wrt ..plt 对其进行尾调用,或在其周围放置一个虚拟的 push/pop。
猜你喜欢
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多