从 gcc 调用一个简单的汇编程序
Calling a simple assembly program from gcc
我有以下程序通过 printf
函数打印数字:
format: .ascii "Your number is: %d.\n[=10=]"
.globl main
main:
// printf('%d', 55);
mov $format, %rdi
mov , %rsi
mov [=10=], %eax
// call printf with 16-byte aligned stack:
sub , %rsp
call printf
add , %rsp
// return 0;
mov [=10=], %eax
ret
$ gcc -no-pie int.s -o int; ./int
Your number is: 55.
我在写这篇文章的时候有几个问题:
sub ...add
是否可以很好地保持对齐?例如,与 push %rbp...pop %rbp
. 相同
- 我尝试添加一些
.data
和 .rodata
以及 .text
directives/sections 但每次我都会得到 warning/error。为什么在通过 gcc
调用汇编程序时不允许这些?例如,C 如何知道“format”是 .data
而“main”在 .text
中?
mov [=21=], %eax; ret
是从程序集退出 C
主函数的正确方法吗?
- 最后,如果不执行
-no-pie
,我需要对这个程序进行哪些修改 运行?
Does the sub ...add
work fine to preserve alignment? For example, the same as doing push %rbp...pop %rbp
.
是的。如果你阅读了 push
和 pop
的指令描述,你会发现它们对堆栈指针有相同的影响,除了 reading/writing 对寄存器和堆栈内存你不关心。但是 push
和 pop
是较短的指令。
How, for example, does C know that "format" is .data
and "main" is in .text
?
除非你告诉它,否则它不会,他们也不会。如果使用 objdump --full-contents
转储可执行文件,您会看到您的字符串已与其他所有内容一起放入 .text
中,因为您从未告诉汇编程序否则会这样做。
Is mov [=20=], %eax; ret
the proper way to exit the C
main function from assembly?
是的,尽管 xor %eax, %eax ; ret
效率更高。
Finally, what modifications would I need to make this program run without doing -no-pie
?
不允许在与位置无关的可执行文件中使用绝对地址作为立即数,因此 mov $format, %rdi
不好。而是使用 RIP 相对寻址:lea format(%rip), %rdi
。其他都还好。
我有以下程序通过 printf
函数打印数字:
format: .ascii "Your number is: %d.\n[=10=]"
.globl main
main:
// printf('%d', 55);
mov $format, %rdi
mov , %rsi
mov [=10=], %eax
// call printf with 16-byte aligned stack:
sub , %rsp
call printf
add , %rsp
// return 0;
mov [=10=], %eax
ret
$ gcc -no-pie int.s -o int; ./int
Your number is: 55.
我在写这篇文章的时候有几个问题:
sub ...add
是否可以很好地保持对齐?例如,与push %rbp...pop %rbp
. 相同
- 我尝试添加一些
.data
和.rodata
以及.text
directives/sections 但每次我都会得到 warning/error。为什么在通过gcc
调用汇编程序时不允许这些?例如,C 如何知道“format”是.data
而“main”在.text
中? mov [=21=], %eax; ret
是从程序集退出C
主函数的正确方法吗?- 最后,如果不执行
-no-pie
,我需要对这个程序进行哪些修改 运行?
Does the
sub ...add
work fine to preserve alignment? For example, the same as doingpush %rbp...pop %rbp
.
是的。如果你阅读了 push
和 pop
的指令描述,你会发现它们对堆栈指针有相同的影响,除了 reading/writing 对寄存器和堆栈内存你不关心。但是 push
和 pop
是较短的指令。
How, for example, does C know that "format" is
.data
and "main" is in.text
?
除非你告诉它,否则它不会,他们也不会。如果使用 objdump --full-contents
转储可执行文件,您会看到您的字符串已与其他所有内容一起放入 .text
中,因为您从未告诉汇编程序否则会这样做。
Is
mov [=20=], %eax; ret
the proper way to exit theC
main function from assembly?
是的,尽管 xor %eax, %eax ; ret
效率更高。
Finally, what modifications would I need to make this program run without doing
-no-pie
?
不允许在与位置无关的可执行文件中使用绝对地址作为立即数,因此 mov $format, %rdi
不好。而是使用 RIP 相对寻址:lea format(%rip), %rdi
。其他都还好。