为什么在小型asm示例中我的结果会有所不同? [英] Why do my results different following along the tiny asm example?

查看:65
本文介绍了为什么在小型asm示例中我的结果会有所不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读此页面 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 不是默认设置,即使将 -nostdlib 配置为在默认情况下将PIE制作为PIE.使用 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆