[英]Linking and calling printf from gas assembly
There are a few related questions to this which I've come across, such as Printf with gas assembly and Calling C printf from assembly but I'm hoping this is a bit different.我遇到了一些与此相关的问题,例如带有气体组件的 Printf 和Calling C printf 与组件但我希望这有点不同。
I have the following program:我有以下程序:
.section .data
format:
.ascii "%d\n"
.section .text
.globl _start
_start:
// print "55"
mov $format, %rdi
mov $55, %rsi
mov $0, %eax
call printf # how to link?
// exit
mov $60, %eax
mov $0, %rdi
syscall
Two questions related to this:与此相关的两个问题:
as
(gas) and ld
to link this to the printf
function, using _start
as the entry point?是否可以仅使用as
(gas) 和ld
将其链接到printf
function,使用_start
作为入口点? If so, how could that be done?如果是这样,那该怎么做?_start
to main
, what would be the gcc
invocation to run things properly?如果不是,除了将_start
更改为main
之外,还有什么gcc
调用可以正常运行? It is possible to use ld
, but not recommended: if you use libc functions, you need to initialise the C runtime.可以使用ld
,但不推荐:如果使用 libc 函数,则需要初始化 C 运行时。 That is done automatically if you let the C compiler provide _start
and start your program as main
.如果您让 C 编译器提供_start
并将您的程序作为main
启动,那将自动完成。 If you use the libc but not the C runtime initialisation code, it may seem to work, but it can also lead to strange spurious failure.如果您使用 libc 而不是 C 运行时初始化代码,它可能看起来有效,但也可能导致奇怪的虚假故障。
If you start your program from main
(your second case) instead, it's as simple as doing gcc -o program program.s
where program.s
is your source file.如果你从main
(你的第二种情况)开始你的程序,它就像做gcc -o program program.s
一样简单,其中program.s
是你的源文件。 On some Linux distributions you may also need to supply -no-pie
as your program is not written in PIC style (don't worry about this for now).在某些 Linux 发行版上,您可能还需要提供-no-pie
,因为您的程序不是以 PIC 样式编写的(暂时不用担心)。
Note also that I recommend not mixing libc calls with raw system calls.另请注意,我建议不要将 libc 调用与原始系统调用混合使用。 Instead of doing a raw exit system call, call the C library function exit
.无需执行原始退出系统调用,而是调用 C 库 function exit
。 This lets the C runtime deinitialise itself correctly, including flushing any IO streams.这让 C 运行时可以正确地自行取消初始化,包括刷新任何 IO 流。
Now if you assemble and link your program as I said in the first paragraph, you'll notice that it might crash.现在,如果您按照我在第一段中所说的那样组装和链接您的程序,您会注意到它可能会崩溃。 This is because the stack needs to be aligned to a multiple of 16 bytes on calls to functions.这是因为在调用函数时堆栈需要与 16 字节的倍数对齐。 You can ensure this alignment by pushing a qword of data on the stack at the beginning of each of your functions (remember to pop it back off at the end).您可以通过在每个函数的开头将一个 qword 数据推送到堆栈上来确保此 alignment(请记住在最后将其弹出)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.