Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 正确比较Arm机器代码和部件_Assembly_Arm_Machine Code - Fatal编程技术网

Assembly 正确比较Arm机器代码和部件

Assembly 正确比较Arm机器代码和部件,assembly,arm,machine-code,Assembly,Arm,Machine Code,我已经习惯于查看Arm上的汇编输出,并且认为浏览机器代码会很有趣,因为我有参考资料,可以很容易地看到我面前的所有内容。然而,我发现它与我期望看到的不符。这告诉我,我在某个地方犯了一点错误。也许有人能帮我。这是我的asm: .arch armv8-m.main .eabi_attribute 20, 1 .eabi_attribute 21, 1 .eabi_attribute 23, 3 .eabi_attribute 24, 1 .eabi_at

我已经习惯于查看Arm上的汇编输出,并且认为浏览机器代码会很有趣,因为我有参考资料,可以很容易地看到我面前的所有内容。然而,我发现它与我期望看到的不符。这告诉我,我在某个地方犯了一点错误。也许有人能帮我。这是我的asm:

    .arch armv8-m.main
    .eabi_attribute 20, 1
    .eabi_attribute 21, 1
    .eabi_attribute 23, 3
    .eabi_attribute 24, 1
    .eabi_attribute 25, 1
    .eabi_attribute 26, 1
    .eabi_attribute 30, 6
    .eabi_attribute 34, 1
    .eabi_attribute 18, 4
    .file   "arm_test.c"
    .text
    .align  1
    .global main
    .syntax unified
    .thumb
    .thumb_func
    .fpu softvfp
    .type   main, %function
main:
    @ args = 0, pretend = 0, frame = 8
    @ frame_needed = 1, uses_anonymous_args = 0
    @ link register save eliminated.
    push    {r7}
    sub sp, sp, #12
    add r7, sp, #0
    movs    r3, #2
    str r3, [r7, #4]
    ldr r3, [r7, #4]
    adds    r3, r3, #13
    str r3, [r7]
    movs    r3, #0
    mov r0, r3
    adds    r7, r7, #12
    mov sp, r7
    @ sp needed
    pop {r7}
    bx  lr
    .size   main, .-main
    .ident  "GCC: (GNU Arm Embedded Toolchain 9-2020-q2-update) 9.3.1 20200408 (release)"
下面是我的十六进制输出的开始(来自objcopy):


现在,由于arm默认为little endian,我希望第一个字节(0x47)是一个PUSH命令。但是0x47=0B010000111,这在我看来像是一条BLX指令。好吧,也许是从树枝开始的?如果这是真的,那么由于它是一条16位指令,下一条指令以0x46开始(我想是吧?)。现在0x46=0B010000110看起来像一条MOV(另一条16位指令)。。。但现在已经开始觉得这和ASM不符了。。。因此,由于我显然没有正确地看待这一点,有人能告诉我正确的开始位置吗?

按照原样编写代码

arm-none-eabi-as so.s -o so.o
arm-none-eabi-objdump -d so.o

so.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <main>:
   0:   b480        push    {r7}
   2:   b083        sub sp, #12
   4:   af00        add r7, sp, #0
   6:   2302        movs    r3, #2
   8:   607b        str r3, [r7, #4]
   a:   687b        ldr r3, [r7, #4]
   c:   330d        adds    r3, #13
   e:   603b        str r3, [r7, #0]
  10:   2300        movs    r3, #0
  12:   4618        mov r0, r3
  14:   370c        adds    r7, #12
  16:   46bd        mov sp, r7
  18:   bc80        pop {r7}
  1a:   4770        bx  lr
注:

虽然你可能对英特尔和摩托罗拉有强烈的宗教立场。通过S3行,您可以获得完整的地址。底线是二进制的使用者,您必须匹配使用者使用的格式(mcu编程工具等)。当我制作自己的工具时,启用S3的srec是一个不错的选择。许多工具直接支持elf文件,因此通常不需要这些文件。其他支持原始二进制图像(-O二进制),因此同样不需要十六进制格式。YMMV

嗯,push{r7}很明显,在十六进制文件中只有一个b4,它是一个校验和

这条线有一个bx lr

:10802C00024B13B1024800F047B9 7047 0000000042
所以第一次尝试是

.thumb
.inst.n 0x4B02
.inst.n 0xB113  
.inst.n 0x4802
.inst.n 0xF000
.inst.n 0xB947
.inst.n 0x4770
.inst.n 0x0000
.inst.n 0x0000

00000000 <.text>:
   0:   4b02        ldr r3, [pc, #8]    ; (c <.text+0xc>)
   2:   b113        cbz r3, a <.text+0xa>
   4:   4802        ldr r0, [pc, #8]    ; (10 <.text+0x10>)
   6:   f000 b947   b.w 298 <.text+0x298>
   a:   4770        bx  lr
   c:   0000        movs    r0, r0
所以我在ihex文件中没有看到您的(机器)代码

我们也没有看到每四个字节有很多0xEx字节,因此它可能不是全尺寸arm指令,尽管0x8000有点暗示这是作为全尺寸arm的linux二进制文件构建的

objcopy从对象生成十六进制类型文件(elf,不是链接的elf)

我们可以看到前面的0xb480和后面的0x4770。请注意,有些工具不会对十六进制文件进行字节交换,您可能会看到4770而不是7047,这没什么错,只是世界有时是这样的……十六进制文件的创建者和使用者都需要在这方面保持同步

编辑

非常小,但这是你想要做的事情

flash.s(向量表和引导)

flash.ld(链接器脚本)

建造

检查

08000000 <reset-0x8>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000009    stmdaeq r0, {r0, r3}

08000008 <reset>:
 8000008:   f000 f801   bl  800000e <main>
 800000c:   e7fe        b.n 800000c <reset+0x4>

0800000e <main>:
 800000e:   b480        push    {r7}
 8000010:   b083        sub sp, #12
 8000012:   af00        add r7, sp, #0
 8000014:   2302        movs    r3, #2
 8000016:   607b        str r3, [r7, #4]
 8000018:   687b        ldr r3, [r7, #4]
 800001a:   330d        adds    r3, #13
 800001c:   603b        str r3, [r7, #0]
 800001e:   2300        movs    r3, #0
 8000020:   4618        mov r0, r3
 8000022:   370c        adds    r7, #12
 8000024:   46bd        mov sp, r7
 8000026:   bc80        pop {r7}
 8000028:   4770        bx  lr

(naturally you can make an ihex or whatever other format you want)

S00A0000736F2E7372656338
S31508000000001000200900000800F001F8FEE780B49F
S3150800001083B000AF02237B607B680D333B6000230F
S30F0800002018460C37BD4680BC704731
S70500000000FA

hexdump -C so.bin
00000000  00 10 00 20 09 00 00 08  00 f0 01 f8 fe e7 80 b4  |... ............|
00000010  83 b0 00 af 02 23 7b 60  7b 68 0d 33 3b 60 00 23  |.....#{`{h.3;`.#|
00000020  18 46 0c 37 bd 46 80 bc  70 47                    |.F.7.F..pG|
0000002a
几乎相同,这里也将其更改为-m33

arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m33 flash.s -o flash.o
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=cortex-m33 -mthumb -c so.c -o so.o
arm-none-eabi-ld -nostdlib -nostartfiles -T flash.ld flash.o so.o -o so.elf
arm-none-eabi-objdump -D so.elf > so.list
arm-none-eabi-objcopy -O binary so.elf so.bin
给予

08000000:
8000000:20001000和CS r1、r0、r0
8000004:08000009 stmdaeq r0,{r0,r3}
08000008 :
8000008:f000 f802 bl 8000010
800000c:e7fe b.n 800000c
...
08000010 :
8000010:2005年电影r0,#5
8000012:4770 bx lr
0x08000000即使不是所有STM32(大约0x00200000),也是最多的,0x01000000是我所知道的ti(msp432s,可能是以前的发光显微镜)。如果我没记错的话,nxp可能是0x00000000。我不记得北欧或其他国家的情况。只需阅读文档即可。从技术上讲,所有这些都适用于使用0x00000000的小型二进制文件,但例如,NucleoBoards(stm32)不允许您在上面复制.bin文件,如果地址错误,则会出错。飞思卡尔或其他人对复制bin文件有更多的规定

你真的需要自己控制引导程序和链接器脚本,即使你从别人那里借用它。C库或hal库也将扮演一个角色,也许这就是您实际构建东西的方式,因为那里的makefiles正在使用hal/cmsis/other库中的引导和链接器脚本。出于某种原因,许多人会制作大量的链接器脚本,试图解决所有问题,如引导、C库(如果有的话)、芯片库、编译器库等,而不是精简和简单,让事情自然地工作。我建议从minimal开始,然后再变得更复杂,但这样就牺牲了供应商提供的C库和hal/随便什么库


当你进入纯金属时,清单上的一件事就是要么使用其他人的沙箱,要么掌握工具。看起来您希望掌握这些工具,这很好,上面的内容使它看起来很简单……如果您不使其复杂化,那么它仍然可以保持简单。

按原样编写代码

arm-none-eabi-as so.s -o so.o
arm-none-eabi-objdump -d so.o

so.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <main>:
   0:   b480        push    {r7}
   2:   b083        sub sp, #12
   4:   af00        add r7, sp, #0
   6:   2302        movs    r3, #2
   8:   607b        str r3, [r7, #4]
   a:   687b        ldr r3, [r7, #4]
   c:   330d        adds    r3, #13
   e:   603b        str r3, [r7, #0]
  10:   2300        movs    r3, #0
  12:   4618        mov r0, r3
  14:   370c        adds    r7, #12
  16:   46bd        mov sp, r7
  18:   bc80        pop {r7}
  1a:   4770        bx  lr
注:

虽然你可能对英特尔和摩托罗拉有强烈的宗教立场。通过S3行,您可以获得完整的地址。底线是二进制的使用者,您必须匹配使用者使用的格式(mcu编程工具等)。当我制作自己的工具时,启用S3的srec是一个不错的选择。许多工具直接支持elf文件,因此通常不需要这些文件。其他支持原始二进制图像(-O二进制),因此同样不需要十六进制格式。YMMV

嗯,push{r7}很明显,在十六进制文件中只有一个b4,它是一个校验和

这条线有一个bx lr

:10802C00024B13B1024800F047B9 7047 0000000042
所以第一次尝试是

.thumb
.inst.n 0x4B02
.inst.n 0xB113  
.inst.n 0x4802
.inst.n 0xF000
.inst.n 0xB947
.inst.n 0x4770
.inst.n 0x0000
.inst.n 0x0000

00000000 <.text>:
   0:   4b02        ldr r3, [pc, #8]    ; (c <.text+0xc>)
   2:   b113        cbz r3, a <.text+0xa>
   4:   4802        ldr r0, [pc, #8]    ; (10 <.text+0x10>)
   6:   f000 b947   b.w 298 <.text+0x298>
   a:   4770        bx  lr
   c:   0000        movs    r0, r0
所以我在ihex文件中没有看到您的(机器)代码

我们也没有看到每四个字节有很多0xEx字节,因此它可能不是全尺寸arm指令,尽管0x8000有点暗示这是作为全尺寸arm的linux二进制文件构建的

objcopy从对象生成十六进制类型文件(elf,不是链接的elf)

我们可以看到前面的0xb480和后面的0x4770。请注意,有些工具不会对十六进制文件进行字节交换,您可能会看到4770而不是7047,这没什么错,只是世界有时是这样的……十六进制文件的创建者和使用者都需要在这方面保持同步

编辑

非常小,但这是你想要做的事情

flash.s(向量表和引导)

flash.ld(链接器脚本)

别伊
MEMORY
{
    bob : ORIGIN = 0x08000000, LENGTH = 0x1000
    ted : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .hello : { *(.text*) } > bob
    .world : { *(.data*) } > ted
}
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m23 flash.s -o flash.o
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m23 -mthumb -c so.s -o so.o
arm-none-eabi-ld -nostdlib -nostartfiles -T flash.ld flash.o so.o -o so.elf
arm-none-eabi-objdump -D so.elf > so.list
arm-none-eabi-objcopy --srec-forceS3 so.elf -O srec so.srec
arm-none-eabi-objcopy -O binary so.elf so.bin
08000000 <reset-0x8>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000009    stmdaeq r0, {r0, r3}

08000008 <reset>:
 8000008:   f000 f801   bl  800000e <main>
 800000c:   e7fe        b.n 800000c <reset+0x4>

0800000e <main>:
 800000e:   b480        push    {r7}
 8000010:   b083        sub sp, #12
 8000012:   af00        add r7, sp, #0
 8000014:   2302        movs    r3, #2
 8000016:   607b        str r3, [r7, #4]
 8000018:   687b        ldr r3, [r7, #4]
 800001a:   330d        adds    r3, #13
 800001c:   603b        str r3, [r7, #0]
 800001e:   2300        movs    r3, #0
 8000020:   4618        mov r0, r3
 8000022:   370c        adds    r7, #12
 8000024:   46bd        mov sp, r7
 8000026:   bc80        pop {r7}
 8000028:   4770        bx  lr

(naturally you can make an ihex or whatever other format you want)

S00A0000736F2E7372656338
S31508000000001000200900000800F001F8FEE780B49F
S3150800001083B000AF02237B607B680D333B6000230F
S30F0800002018460C37BD4680BC704731
S70500000000FA

hexdump -C so.bin
00000000  00 10 00 20 09 00 00 08  00 f0 01 f8 fe e7 80 b4  |... ............|
00000010  83 b0 00 af 02 23 7b 60  7b 68 0d 33 3b 60 00 23  |.....#{`{h.3;`.#|
00000020  18 46 0c 37 bd 46 80 bc  70 47                    |.F.7.F..pG|
0000002a
int main ( void )
{
    return(5);
}
arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m33 flash.s -o flash.o
arm-none-eabi-gcc -Wall -O2 -ffreestanding -mcpu=cortex-m33 -mthumb -c so.c -o so.o
arm-none-eabi-ld -nostdlib -nostartfiles -T flash.ld flash.o so.o -o so.elf
arm-none-eabi-objdump -D so.elf > so.list
arm-none-eabi-objcopy -O binary so.elf so.bin
08000000 <reset-0x8>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000009    stmdaeq r0, {r0, r3}

08000008 <reset>:
 8000008:   f000 f802   bl  8000010 <main>
 800000c:   e7fe        b.n 800000c <reset+0x4>
    ...

08000010 <main>:
 8000010:   2005        movs    r0, #5
 8000012:   4770        bx  lr