为什么在小型asm示例中我的结果会有所不同? [英] Why do my results different following along the tiny asm example?
问题描述
我正在阅读此页面 https://www.muppetlabs.com/〜breadbox/software/tiny/teensy.html
这是示例之一
; tiny.asm
BITS 32
GLOBAL _start
SECTION .text
_start:
mov eax, 1
mov ebx, 42
int 0x80
Here we go:
$ nasm -f elf tiny.asm
$ gcc -Wall -s -nostdlib tiny.o
$ ./a.out ; echo $?
42
Ta-da! And the size?
$ wc -c a.out
372 a.out
但是我没有得到相同的结果.我尝试了 nasm -f elf64
,然后在gcc上尝试了 -m32
(然后再次在clang上).不管我尝试什么,我都无法做到小巧的尺寸.我在Arch Linux上
However I don't get the same results. I tried nasm -f elf64
and then tried -m32
on gcc (then again on clang). No matter what I try I can not get it to be the tiny size. I'm on arch linux
$ cat tiny.asm
; tiny.asm
BITS 32
GLOBAL _start
SECTION .text
_start:
mov eax, 1
mov ebx, 42
int 0x80
[eric@eric test]$ gcc -Wall -s -nostdlib -m32 tiny.o
[eric@eric test]$ stat ./a.out
File: ./a.out
Size: 12780 Blocks: 32 IO Block: 4096 regular file
Device: 2eh/46d Inode: 1279 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 1000/ eric) Gid: ( 1000/ eric)
Access: 2020-12-26 17:19:19.216294869 -0500
Modify: 2020-12-26 17:19:19.216294869 -0500
Change: 2020-12-26 17:19:19.216294869 -0500
Birth: -
推荐答案
-static
不是默认设置,即使将 gcc -m32 -static -nostdlib
获取历史行为.( -static
表示 -no-pie
).请参见静态链接"与静态链接"和不是动态可执行文件";可以从Linux ldd获得?了解更多.
-static
is not the default even with -nostdlib
when GCC is configured to make PIEs by default. Use gcc -m32 -static -nostdlib
to get the historical behaviour. (-static
implies -no-pie
). See What's the difference between "statically linked" and "not a dynamic executable" from Linux ldd? for more.
此外,您可能需要使用 gcc -Wl,-nmagic
或使用自定义链接脚本来禁用其他部分的对齐方式,并可能禁用GCC添加的元数据的其他部分.链接后的最小可执行文件大小现在比2小10倍年前,对于小型程序?
Also, you may need to disable alignment of other sections with gcc -Wl,--nmagic
or using a custom linker script, and maybe disable extra sections of metadata that GCC adds. Minimal executable size now 10x larger after linking than 2 years ago, for tiny programs?
如果不链接任何编译器生成的(从C生成的) .o
文件,则可能没有 .eh_frame
部分.但是,如果您愿意,可以使用 gcc -fno-asynchronous-unwind-tables
禁用它.(另请参见如何从GCC/clang中删除噪声"程序集输出?以获得旨在查看编译器的asm文本输出(而不是可执行文件大小)的一般性提示.
You probably don't have a .eh_frame
section if you're not linking any compiler-generated (from C) .o
files. But if you were, you can disable that with gcc -fno-asynchronous-unwind-tables
. (See also How to remove "noise" from GCC/clang assembly output? for general tips aimed at looking at the compiler's asm text output, moreso than executable size.)
另请参见 GCC + LD + NDISASM =大量的汇编程序指令(ndisasm根本不处理元数据,只处理平面二进制数据,因此它会反汇编"元数据.因此,答案包括有关如何避免其他部分的信息.)
See also GCC + LD + NDISASM = huge amount of assembler instructions (ndisasm doesn't handle metadata at all, only flat binary, so it "disassembles" metadata. So the answer there includes info on how to avoid other sections.)
GCC -Wl,-build-id = none
将避免在可执行文件中包含 .note.gnu.build-id
部分.
GCC -Wl,--build-id=none
will avoid including a .note.gnu.build-id
section in the executable.
$ nasm -felf32 foo.asm
$ gcc -m32 -static -nostdlib -Wl,--build-id=none -Wl,--nmagic foo.o
$ ll a.out
-rwxr-xr-x 1 peter peter 488 Dec 26 18:47 a.out
$ strip a.out
$ ll a.out
-rwxr-xr-x 1 peter peter 248 Dec 26 18:47 a.out
(已在GNU Binutils 2.35.1的x86-64 Arch GNU/Linux,NASM 2.15.05,gcc 10.2, ld
上进行了测试.)
(Tested on x86-64 Arch GNU/Linux, NASM 2.15.05, gcc 10.2, ld
from GNU Binutils 2.35.1.)
您可以使用 readelf -a a.out
来检查可执行文件中的部分(或使用更具体的选项来仅获取 readelf
的大输出.)例如在剥离之前,
You can check on the sections in your executable with readelf -a a.out
(or use a more specific option to only get part of readelf
's large output.) e.g. before stripping,
$ readelf -S unstripped_a.out
...
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 08048060 000060 00000c 00 AX 0 0 16
[ 2] .symtab SYMTAB 00000000 00006c 000070 10 3 3 4
[ 3] .strtab STRTAB 00000000 0000dc 000021 00 0 0 1
[ 4] .shstrtab STRTAB 00000000 0000fd 000021 00 0 0 1
顺便说一句,顺便说一句,除非您正在编写,否则您肯定不是不是要在使用 BITS 32
的文件上使用 nasm -felf64
内核或从64位长模式切换到32位兼容模式的内容.将32位机器代码放在64位目标文件中是没有帮助的.当您希望原始二进制模式起作用时,请仅使用 BITS
(在该tiny-ELF教程中稍后).当您创建一个 .o
链接时,这只会使您自己陷入困境.不要做(尽管如果您正确使用与您的BITS指令匹配的 nasm -felf32
并没有什么害处.)
And BTW, you definitely do not want to use nasm -felf64
on a file that uses BITS 32
, unless you're writing a kernel or something that switches from 64-bit long mode to 32-bit compat mode. Putting 32-bit machine code in a 64-bit object file is not helpful. Only ever use BITS
when you want raw binary mode to work (later in that tiny-ELF tutorial). When you're making a .o
to link, it only makes it possible to shoot yourself in the foot; don't do it. (Although it's not harmful if you do properly use nasm -felf32
that matches your BITS directive.)
这篇关于为什么在小型asm示例中我的结果会有所不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!