joe 发表于 2022-10-10 11:28:00

ARM汇编指令裸板操作LED

//https://blog.csdn.net/szm1234/article/details/109764869
.global _start @全局标号

_start:
    /* 使能所有外设时钟 */
    ldr r0, = 0x020c4068   @CCGR0
    ldr r1, = 0xffffffff   @要向CCGR0写入的数据
    str r1,         @将0xffffffff写入到CCGR0

    ldr r0, = 0x020c406c   @CCGR1
    str r1,         @将0xffffffff写入到CCGR1

    ldr r0, = 0x020c4070   @CCGR2
    str r1,         @将0xffffffff写入到CCGR2

    ldr r0, = 0x020c4074   @CCGR3
    str r1,         @将0xffffffff写入到CCGR3

    ldr r0, = 0x020c4078   @CCGR4
    str r1,         @将0xffffffff写入到CCGR4

    ldr r0, = 0x020c407c   @CCGR5
    str r1,         @将0xffffffff写入到CCGR5

    ldr r0, = 0x020c4080   @CCGR6
    str r1,         @将0xffffffff写入到CCGR6


    /* IO复用 配置GPIO1_IO03 PIN的复用为GPIO,也就是设置寄存器
   * IOMUXC_SW_MUX_CTL_PAD_GPIO03 = 5
   * IOMUXC_SW_MUX_CTL_PAD_GPIO03 地址为0x20e022ch
   */

    ldr r0, = 0x20e022c   @IOMUXC_SW_MUX_CTL_PAD_GPIO03
    ldr r1, = 0x00000101   @要向IOMUXC_SW_MUX_CTL_PAD_GPIO03写入的数据
    str r1,         @将0x00000101 = 5写入到IOMUXC_SW_MUX_CTL_PAD_GPIO03

    /* 配置GPIO01_IO3的电气属性 也就是寄存器:
   * IOMUXC_SW_PAD_CTL_PAD_GPIO03
   * IOMUXC_SW_MUX_CTL_PAD_GPIO03 寄存器地址为0x20e05fch
   *
   * bit0:       0   低速率
   * bit5:3      110   R0/6驱动能力
   * bit7:6      10    100MHz速度
   * bit11:      0   关闭开路输出
   * bit12:      1   使能pull/kepper
   * bit15:14:   00    默认100K下拉
   * bit16:      0   关闭hys
   */

    ldr r0, = 0x20e05fc
    ldr r1, = 0x10b0
    str r1,         @将0x0x10b0写入到IOMUXC_SW_PAD_CTL_PAD_GPIO03

    /* 设置GPIO
   * 设置GPIO1_GDIR寄存器,设置GPIO1_GPIO03为输出
   * GPIO1_GDIR寄存器地址为209c004,设置GPIO1_GDIR寄存器bit3为1
   * 也就是设置GPIO1_IO03为输出
   */

   ldr r0, = 0x209c004
   ldr r1, = 0x8
   str r1,         

   /* 设置GPIO1_IO03 为1
      * GPIO1_DR寄存器地址为0x0209c000
      */

      ldr r0, = 0x0209c00
      ldr r1, = 1
      str r1,

loop:                     @b loop 在73 74行死循环
    b loop

在makefile文件中:
imx6led:imx6led.o
        arm-none-eabi-ld -Ttext=0x7000 -Map imx6led.map -o imx6led.elf $^
        arm-none-eabi-objcopy -O binary imx6led.elf imx6led.bin

(注意上在红色字体,后面反汇编之后可以看到这个基址值)
arm-none-eabi-objdump -D imx6led.elf >> im6leddisasm.dis
im6leddisasm.dis内容如下:

imx6led.elf:   file format elf32-littlearm


Disassembly of section .text:

00007000 <_start>:
    7000:        e59f0068         ldr        r0,         ; 7070 <loop+0x4>
    7004:        e3e01000         mvn        r1, #0
    7008:        e5801000         str        r1,
    700c:        e59f0060         ldr        r0,         ; 7074 <loop+0x8>
    7010:        e5801000         str        r1,
    7014:        e59f005c         ldr        r0,         ; 7078 <loop+0xc>
    7018:        e5801000         str        r1,
    701c:        e59f0058         ldr        r0,         ; 707c <loop+0x10>
    7020:        e5801000         str        r1,
    7024:        e59f0054         ldr        r0,         ; 7080 <loop+0x14>
    7028:        e5801000         str        r1,
    702c:        e59f0050         ldr        r0,         ; 7084 <loop+0x18>
    7030:        e5801000         str        r1,
    7034:        e59f004c         ldr        r0,         ; 7088 <loop+0x1c>
    7038:        e5801000         str        r1,
    703c:        e59f0048         ldr        r0,         ; 708c <loop+0x20>
    7040:        e59f1048         ldr        r1,         ; 7090 <loop+0x24>
    7044:        e5801000         str        r1,
    7048:        e59f0044         ldr        r0,         ; 7094 <loop+0x28>
    704c:        e59f1044         ldr        r1,         ; 7098 <loop+0x2c>
    7050:        e5801000         str        r1,
    7054:        e59f0040         ldr        r0,         ; 709c <loop+0x30>
    7058:        e3a01008         mov        r1, #8
    705c:        e5801000         str        r1,
    7060:        e59f0038         ldr        r0,         ; 70a0 <loop+0x34>
    7064:        e3a01001         mov        r1, #1
    7068:        e5801000         str        r1,

0000706c <loop>:
    706c:        eafffffe         b        706c <loop>
    7070:        020c4068         andeq        r4, ip, #104        ; 0x68
    7074:        020c406c         andeq        r4, ip, #108        ; 0x6c
    7078:        020c4070         andeq        r4, ip, #112        ; 0x70
    707c:        020c4074         andeq        r4, ip, #116        ; 0x74
    7080:        020c4078         andeq        r4, ip, #120        ; 0x78
    7084:        020c407c         andeq        r4, ip, #124        ; 0x7c
    7088:        020c4080         andeq        r4, ip, #128        ; 0x80
    708c:        020e022c         andeq        r0, lr, #44, 4        ; 0xc0000002
    7090:        00000101         andeq        r0, r0, r1, lsl #2
    7094:        020e05fc         andeq        r0, lr, #252, 10        ; 0x3f000000
    7098:        000010b0         strheq        r1, , -r0
    709c:        0209c004         andeq        ip, r9, #4
    70a0:        00209c00         eoreq        r9, r0, r0, lsl #24

Disassembly of section .debug_aranges:

00000000 <.debug_aranges>:
   0:        0000001c         andeq        r0, r0, ip, lsl r0
   4:        00000002         andeq        r0, r0, r2
   8:        00040000         andeq        r0, r4, r0
   c:        00000000         andeq        r0, r0, r0
10:        00007000         andeq        r7, r0, r0
14:        000000a4         andeq        r0, r0, r4, lsr #1
        ...

Disassembly of section .debug_info:

00000000 <.debug_info>:
   0:        0000004c         andeq        r0, r0, ip, asr #32
   4:        00000002         andeq        r0, r0, r2
   8:        01040000         mrseq        r0, (UNDEF: 4)
   c:        00000000         andeq        r0, r0, r0
10:        00007000         andeq        r7, r0, r0
14:        000070a4         andeq        r7, r0, r4, lsr #1
18:        36786d69         ldrbtcc        r6, , -r9, ror #26
1c:        2e64656c         cdpcs        5, 6, cr6, cr4, cr12, {3}
20:        3a480073         bcc        12001f4 <_stack+0x11801f4>
24:        504d545c         subpl        r5, sp, ip, asr r4
28:        7074665c         rsbsvc        r6, r4, ip, asr r6
2c:        76726573                         ; <UNDEFINED> instruction: 0x76726573
30:        6f727265         svcvs        0x00727265
34:        615c746f         cmpvs        ip, pc, ror #8
38:        62396d72         eorsvs        r6, r9, #7296        ; 0x1c80
3c:        00657261         rsbeq        r7, r5, r1, ror #4
40:        20554e47         subscs        r4, r5, r7, asr #28
44:        32205341         eorcc        r5, r0, #67108865        ; 0x4000001
48:        2e36322e         cdpcs        2, 3, cr3, cr6, cr14, {1}
4c:        80010030         andhi        r0, r1, r0, lsr r0

Disassembly of section .debug_abbrev:

00000000 <.debug_abbrev>:
   0:        10001101         andne        r1, r0, r1, lsl #2
   4:        12011106         andne        r1, r1, #-2147483647        ; 0x80000001
   8:        1b080301         blne        200c14 <_stack+0x180c14>
   c:        13082508         movwne        r2, #34056        ; 0x8508
10:        00000005         andeq        r0, r0, r5

Disassembly of section .debug_line:

00000000 <.debug_line>:
   0:        00000066         andeq        r0, r0, r6, rrx
   4:        00200002         eoreq        r0, r0, r2
   8:        01020000         mrseq        r0, (UNDEF: 2)
   c:        000d0efb         strdeq        r0, , -fp
10:        01010101         tsteq        r1, r1, lsl #2
14:        01000000         mrseq        r0, (UNDEF: 0)
18:        00010000         andeq        r0, r1, r0
1c:        36786d69         ldrbtcc        r6, , -r9, ror #26
20:        2e64656c         cdpcs        5, 6, cr6, cr4, cr12, {3}
24:        00000073         andeq        r0, r0, r3, ror r0
28:        05000000         streq        r0,
2c:        00700002         rsbseq        r0, r0, r2
30:        2f2f1700         svccs        0x002f1700
34:        2f302f30         svccs        0x00302f30
38:        2f302f30         svccs        0x00302f30
3c:        2f302f30         svccs        0x00302f30
40:        032f2f36                         ; <UNDEFINED> instruction: 0x032f2f36
44:        2f2f2e0f         svccs        0x002f2e0f
48:        342f2f36         strtcc        r2, , #-3894        ; 50 <_start-0x6fb0>
4c:        03312f2f         teqeq        r1, #47, 30        ; 0xbc
50:        322e7fbc         eorcc        r7, lr, #188, 30        ; 0x2f0
54:        31313131         teqcc        r1, r1, lsr r1
58:        2e090331         mcrcs        3, 0, r0, cr9, cr1, {1}
5c:        2e10032f         cdpcs        3, 1, cr0, cr0, cr15, {1}
60:        2e09032f         cdpcs        3, 0, cr0, cr9, cr15, {1}
64:        00020236         andeq        r0, r2, r6, lsr r2
68:        Address 0x00000068 is out of bounds.


Disassembly of section .ARM.attributes:

00000000 <_stack-0x80000>:
   0:        00001341         andeq        r1, r0, r1, asr #6
   4:        61656100         cmnvs        r5, r0, lsl #2
   8:        01006962         tsteq        r0, r2, ror #18
   c:        00000009         andeq        r0, r0, r9
10:        01080106         tsteq        r8, r6, lsl #2



joe 发表于 2022-10-10 13:22:02

很明显可以看到,第一句汇编语句: ldr r0, = 0x020c4068,汇编之后的最终结果是:
    7000:      e59f0068         ldr      r0,       ; 7070 <loop+0x4>
    7004:      e3e01000         mvn      r1, #0对应原代码中的ldr r1,#0xffffffff (mvn指令将源按位取反再传送)
    7008:      e5801000         str      r1,
同时,我们在这个.text节的末尾可以看到:
0000706c <loop>:
    706c:      eafffffe         b      706c <loop>
    7070:      020c4068         andeq      r4, ip, #104      ; 0x68
也就是说在原来的源码:
loop:                     
    b loop
之后编译器自动放置了一些数据,实际上就是源代码中的立即数值0x020c4068等。

joe 发表于 2022-10-10 14:19:08

如果将源代码改为:
_start:
    /* 使能所有外设时钟 */
ldr r0, =0x10 @ = 0x020c4068   @CCGR0
    ldr r1, =0xff @= 0xffffffff   @要向CCGR0写入的数据

反汇编之后可以看到如下代码:
00007000 <_start>:
    7000:        e3a00010         mov        r0, #16
    7004:        e3a010ff         mov        r1, #255        ; 0xff
    7008:        e5801000         str        r1,

joe 发表于 2022-10-11 11:14:11

注意,
7000:      e59f0068         ldr      r0,       ; 7070 <loop+0x4>
和:
7070:      020c4068         andeq      r4, ip, #104      ; 0x68
这二句可知,offset其实是0x70=112,并不是104,那为什么呢?
这是因为我的实验硬件平台满足:
ARM7的三级流水线,PC=PC+8,
ARM9的五级流水线,也是PC=PC+8,
根本的原因是,两者的流水线设计中,指令的Execute执行阶段,都是处于流水线的第三级
所以:104+8=112正确。
页: [1]
查看完整版本: ARM汇编指令裸板操作LED