博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux汇编代码执行函数,linux – 使用GNU汇编程序在x86_64中调用printf
阅读量:4696 次
发布时间:2019-06-09

本文共 1421 字,大约阅读时间需要 4 分钟。

此代码存在许多问题. Linux使用的

AMD64 System V ABI调用约定需要一些东西.它要求在CALL之前堆栈至少为16字节(或32字节)对齐:

The end of the input argument area shall be aligned on a 16 (32,if __m256 is

passed on stack) byte boundary.

在C运行时调用主函数之后,堆栈未对齐8,因为返回指针被CALL放在堆栈上.要重新对齐到16字节边界,您可以简单地将任何通用寄存器推入堆栈并在最后将其POP关闭.

调用约定还要求AL包含用于变量参数函数的向量寄存器的数量:

%al is used to indicate the number of vector arguments passed to a function requiring a variable number of arguments

printf是一个可变参数函数,因此需要设置AL.在这种情况下,您不会在向量寄存器中传递任何参数,因此您可以将AL设置为0.

当$format指针已经是地址时,你也取消引用它.所以这是错的:

mov $format,%rbx

mov (%rbx),%rdi

这将获取格式的地址并将其放在RBX中.然后在RBX中获取该地址的8个字节并将它们放在RDI中. RDI需要是指向字符串的指针,而不是字符本身.这两行可以替换为:

lea format(%rip),%rdi

这使用RIP相对寻址.

你也应该NUL终止你的字符串.您可以在x86平台上使用.asciz,而不是使用.ascii.

您的程序的工作版本可能如下所示:

# global data #

.data

format: .asciz "%d\n"

.text

.global main

main:

push %rbx

lea format(%rip),%rdi

mov $1,%esi # Writing to ESI zero extends to RSI.

xor %eax,%eax # Zeroing EAX is efficient way to clear AL.

call printf

pop %rbx

ret

其他建议/建议

您还应该从64位Linux ABI中了解到,调用约定还需要您编写的函数以保护某些寄存器.登记册清单及是否应予保留如下:

任何在Preserved中说“是”的寄存器

注册列是您必须确保在您的功能中保留的列.函数main与任何其他C函数一样.

如果你有你知道的字符串/数据只读,你可以用.section .rodata而不是.data将它们放在.rodata部分.

在64位模式下:如果您的目标操作数是32位寄存器,则cpu将在整个64位寄存器中对寄存器进行零扩展.这可以节省指令编码上的字节.

您的可执行文件可能被编译为与位置无关的代码.您可能会收到类似于以下错误:

relocation R_X86_64_PC32 against symbol `printf@@GLIBC_2.2.5′ can not be used when making a shared object; recompile with -fPIC

要修复此问题,您必须以这种方式调用外部函数printf:

call printf@plt

转载地址:http://imcup.baihongyu.com/

你可能感兴趣的文章
[leetcode] Happy Number
查看>>
Java第五周学习总结
查看>>
j.c.Warnsdorff马踏棋盘算法
查看>>
git私服
查看>>
the openning
查看>>
python 字符串 和 print
查看>>
MAC OS下安装Minizip
查看>>
Java_Certificates does not conform to algorithm constraints
查看>>
PAT 1027. Colors in Mars
查看>>
linux定时执行脚本
查看>>
Oauth支持的5类 grant_type 及说明
查看>>
ASP.NET 5 DNX SDK删除旧版本
查看>>
Android ListView 九大重要属性详细分析
查看>>
[LeetCode] 670. Maximum Swap 最大置换
查看>>
CC++中sizeof函数的用法
查看>>
SPFA 算法详解( 强大图解,不会都难!) (转)
查看>>
正则表达式验证
查看>>
QUIC:基于udp的传输新技术
查看>>
java常见面试题及部分答案
查看>>
【HTML代码】访问页面时,拨打页面中的电话号码
查看>>