Arm的汇编指令如何计算文件大小

How to calculate the size of the file with assembly instructions of Arm

将下面的汇编代码转换为二进制后,我的文件大小为 48 字节。因为在 arm 中,每条指令都是 4 个字节。我觉得标签 条目是 - 4 个字节, arr - 3 个字节, eoa - 1 字节, 开始直到循环 - 12 字节, 循环直到停止 - 16 字节, 停止 - 4 个字节, 因此总数是 40 个字节。我不明白为什么它显示 48 个字节。

    .text
entry:  b start
arr:    .byte 10, 20, 30
eoa:
    .align
start:  ldr r0, =eoa
        ldr r1, =arr
        mov r3, #0
loop:   ldrb r2, [r1], #1
        add r3, r3, r2 
        cmp r0, r1
        bne loop
stop:   b stop

user@stretch:~/Desktop/Gnu_Toolchain/Sum_An_Array$ arm-none-eabi-nm -n sum_an_array.elf
         U _start
00000000 t entry
00000004 t arr
00000007 t eoa
00000008 t start
00000014 t loop
00000024 t stop
00010030 T __bss_end__
00010030 T _bss_end__
00010030 T __bss_start
00010030 T __bss_start__
00010030 T __data_start
00010030 T _edata
00010030 T _end
00010030 T __end__
00080000 T _stack

你有两个额外单词的原因是 ldr 不是这里的指令,它是一个伪指令,如 here 所述。

这里,ldr使用了label-expression。汇编程序生成一条 PC 相关的 ldr 指令,并将 label-expression 的值放入文字池中。

这两个额外的词放在你程序的某个地方。然后从这些相对地址加载生成的 ldr 指令。

    .text
entry:  b start
arr:    .byte 10, 20, 30
eoa:
    .align
start:  ldr r0, =eoa
        ldr r1, =arr
        mov r3, #0
loop:   ldrb r2, [r1], #1
        add r3, r3, r2
        cmp r0, r1
        bne loop
stop:   b stop


Disassembly of section .text:

00000000 <entry>:
   0:   ea000000    b   8 <start>

00000004 <arr>:
   4:   140a        .short  0x140a
   6:   1e              .byte   0x1e

00000007 <eoa>:
    ...

00000008 <start>:
   8:   e59f0018    ldr r0, [pc, #24]   ; 28 <stop+0x4>
   c:   e59f1018    ldr r1, [pc, #24]   ; 2c <stop+0x8>
  10:   e3a03000    mov r3, #0

00000014 <loop>:
  14:   e4d12001    ldrb    r2, [r1], #1
  18:   e0833002    add r3, r3, r2
  1c:   e1500001    cmp r0, r1
  20:   1afffffb    bne 14 <loop>

00000024 <stop>:
  24:   eafffffe    b   24 <stop>
  28:   00000007    .word   0x00000007
  2c:   00000004    .word   0x00000004

根据经验,您可以大致了解大小,但只是 assemble 和 disassemble.

fun:
    ldr r0,=0x12345678
    bx lr

00000000 <fun>:
   0:   e51f0000    ldr r0, [pc, #-0]   ; 8 <fun+0x8>
   4:   e12fff1e    bx  lr
   8:   12345678    .word   0x12345678

 
fun:
    ldr r0,=0x00001100
    bx lr

00000000 <fun>:
   0:   e3a00c11    mov r0, #4352   ; 0x1100
   4:   e12fff1e    bx  lr

支持 ldr rd,=label 伪指令的 gnu assembler 等工具将选择最佳指令,其他工具要么不支持它,要么可能不会优化。所以你不能简单地说这将是三个词来实现这两个汇编语言指令。

你可以在没有伪指令的情况下完成它

    .text
entry:  b start
arr:    .byte 10, 20, 30
eoa:
    .align
start:  ldr r0, eoa_add
        ldr r1, arr_add
        mov r3, #0
loop:   ldrb r2, [r1], #1
        add r3, r3, r2
        cmp r0, r1
        bne loop
stop:   b stop
eoa_add: .word eoa
arr_add: .word arr



Disassembly of section .text:

00000000 <entry>:
   0:   ea000000    b   8 <start>

00000004 <arr>:
   4:   140a        .short  0x140a
   6:   1e              .byte   0x1e

00000007 <eoa>:
    ...

00000008 <start>:
   8:   e59f0018    ldr r0, [pc, #24]   ; 28 <eoa_add>
   c:   e59f1018    ldr r1, [pc, #24]   ; 2c <arr_add>
  10:   e3a03000    mov r3, #0

00000014 <loop>:
  14:   e4d12001    ldrb    r2, [r1], #1
  18:   e0833002    add r3, r3, r2
  1c:   e1500001    cmp r0, r1
  20:   1afffffb    bne 14 <loop>

00000024 <stop>:
  24:   eafffffe    b   24 <stop>

00000028 <eoa_add>:
  28:   00000007    .word   0x00000007

0000002c <arr_add>:
  2c:   00000004    .word   0x00000004

并且有更接近的估计。