assembly arm-none-eabi-as如何选择截面对齐?

vom3gejh  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(107)

我正在玩arm-none-eabi-as,试图理解它是如何对齐部分的。我有以下来源:

; source.s
.text
.byte 0xff
.byte 0xff
.byte 0xff

我正在检查生成的对象文件:

$ arm-none-eabi-as -mthumb -o source.o source.s
$ arm-none-eabi-readelf -S source.o
There are 8 section headers, starting at offset 0xec:

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        00000000 000034 000003 00  AX  0   0  1
  [ 2] .data             PROGBITS        00000000 000037 000000 00  WA  0   0  1
  [ 3] .bss              NOBITS          00000000 000037 000000 00  WA  0   0  1
  [ 4] .ARM.attributes   ARM_ATTRIBUTES  00000000 000037 000014 00      0   0  1
  [ 5] .symtab           SYMTAB          00000000 00004c 000060 10      6   6  4
  [ 6] .strtab           STRTAB          00000000 0000ac 000004 00      0   0  1
  [ 7] .shstrtab         STRTAB          00000000 0000b0 00003c 00      0   0  1

.text部分是字节对齐的,包含3个字节。
现在,我向source.s添加一条指令:

; source.s
.text
.byte 0xff
nop
.byte 0xff
.byte 0xff

查看对象文件,现在突然.text部分是半字对齐的:

There are 8 section headers, starting at offset 0x114:

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        00000000 000034 000006 00  AX  0   0  2
  [ 2] .data             PROGBITS        00000000 00003a 000000 00  WA  0   0  1
  [ 3] .bss              NOBITS          00000000 00003a 000000 00  WA  0   0  1
  [ 4] .ARM.attributes   ARM_ATTRIBUTES  00000000 00003a 000014 00      0   0  1
  [ 5] .symtab           SYMTAB          00000000 000050 000080 10      6   8  4
  [ 6] .strtab           STRTAB          00000000 0000d0 000007 00      0   0  1
  [ 7] .shstrtab         STRTAB          00000000 0000d7 00003c 00      0   0  1

在第二种情况下,是什么导致汇编程序决定填充该节?我感到困惑,因为:
1.如果该部分是.data,那么汇编程序无论如何都不会填充它,这是有意义的,但是
1.即使区段是.text,汇编程序也不会填充它,除非它看到一条指令(我可以有尽可能多的数据指令,区段不会在没有指令的情况下被填充),最后

  1. nop指令肯定没有对齐,汇编器对此没有问题,但它仍然决定关心段对齐。
    装配工是如何决定在这里进行填充的?即使我有指令,我是否可以强制汇编程序不填充.text部分?
d5vmydt9

d5vmydt91#

以下是我与binutils人员讨论后了解到的内容:
汇编程序并不关心是否在任何特定部分中编码未对齐的指令。但是,它关心两个方面:
1.任何节的总体节对齐与该节内最对齐的元素匹配,以及
1.用eXecute标志标记的每个部分都被填充以匹配其对齐。
汇编器执行(2),因为稍后这些部分可能需要合并,合并之后所有元素必须保持对齐(因此它填充部分以确保该属性)。
原帖中显示的两种情况的区别在于:

  • 在第一种情况下(没有指令),最对齐的元素是.byte,对齐方式为1,因此整个部分的对齐方式为1,而
  • 在第二种情况下,nop thumb指令成为最对齐的元素,并且该部分现在是2对齐的。

由于示例中的节是.text节,并且设置了X标志,汇编器将在第二种情况下填充节以匹配其对齐方式。尽管如此,nop指令仍然在节内未对齐。

83qze16e

83qze16e2#

装配工是如何决定在这里进行填充的?
thumb(2)模式下的指令必须以16位偏移量开始。如果使用.arm,您将看到填充到32位。它是伊萨的一部分。你的NOP指令将不起作用(如果你以某种方式直接跳转到NOP)。当然,流的其余部分都是垃圾。对于文本部分中的NOP是代码的正常情况,您希望它对齐。指针中的低位通常用于表示“Thumb”或“ARM”模式例程。
即使我有一个指令,我可以强制汇编程序不填充.text部分吗?
将NOP作为数据将是一个奇怪的情况;如果是,如果不需要填充,请自己定义。

.set UNALIGNED_NOP, 0xbf00  ; double check this constant.

你正在以一种完全错误的方式使用工具。如果需要数据,请使用“.rodata”部分。汇编程序的工作是将人类助记符转换为二进制。对于文本部分中的NOP的正常情况,您希望它是可执行的。如果你的用例不支持这些工具,那么会有几十个其他的用例被破坏。比如说

;; basic block
   ;; xxxx
   b  label
   .word xxxx  ; ltorg, etc.
   .word yyyy
   .byte xx
  label:
    add r0, r0, #1 ; crash because it is not aligned.

相关问题