• Thumb指令集程序示例


    在上节课中我们介绍CPU有两种工作状态,一种ARM状态,一种Thumb状态。
    本节课主要介绍Thumb状态及Thumb指令集。

    在012_relocate的程序基础上修改,创建013_thumb_014_003程序,并打开start.S和Makefile代码。

    1. 对Makefile文件进行如下修改。

     1 all: led_on2.o uart.o init.o main.o start.o
     2     
     3     #arm-linux-ld -Ttext 0 -Tdata 0x3000000 start.o led_on2.o uart.o init.o main.o -o sdram.elf
     4     arm-linux-ld -T sdram.lds start.o led_on2.o uart.o init.o main.o -o sdram.elf
     5     arm-linux-objcopy -O binary -S sdram.elf sdram.bin
     6     arm-linux-objdump -D sdram.elf > sdram.dis
     7     
     8 %.o : %.c
     9     arm-linux-gcc -mthumb -c -o $@ $<
    10 %.o : %.S
    11     arm-linux-gcc -c -o $@ $<        # 在汇编文件中不需要做-mthumb的指定,在代码里边进行指定
    12     
    13 .PHONY: clean    
    14 
    15 clean:
    16     rm *.bin *.o *.elf *.dis

    2. 对start.S文件进行如下修改。

     1 .text
     2 .global _start
     3 .code 32        /* 表示后续指令使用ARM指令集 */
     4 
     5 _start:
     6 
     7 ...
     8 
     9 /* 怎么从 ARM_State 切换到 Thumb_State ? */
    10     adr r0, thumb_func            /* 得到thumb_func标号的地址 */
    11     add    r0, r0, #1                /* 为什么 +1 ?bit0 = 1 时, bx就会切换CPU State到thumb State     https://blog.csdn.net/u011449588/article/details/44634977 */
    12     bx    r0             /* bx 命令后边那个值如果最低位为1的话,它会跳转到Thumb指令 */
    13 
    14 .code 16
    15 thumb_func:
    16 
    17     bl sdram_init        /*  */
    18     //bl sdram_init2    /* 用到有初始值的数组,不是位置无关码 */
    19 
    20 ...
    21 
    22 /* 调用main函数 */
    23     //bl main            /* 使用BL命令相对跳转,程序仍然在NOR/片内SRAM上运行 */
    24     /*ldr    pc,    =main*/    /* 绝对跳转,跳到SDRAM */
    25     
    26     ldr    r0, =main
    27     mov pc, r0
    28     
    29 halt:
    30     b halt

    其中,(1) 最后不再允许使用ldr pc,  =main直接对PC进行赋值,而改用 ldr  r0, =main, mov  pc, r0  进行间接赋值。否则出现如下错误:

                    

       (2) 其中 adr r0, thumb_func、add r0, r0, #1

      首先得到thumb_func 标号的地址,并且对其进行+1操作(∵32位处理器指令总是以4字节为单位进行存放,PC每次移动也是进行+4,一般最后一位bit0=0),这里进行+1后,使r0最后一位bit0=1。

      执行到bx r0时,若rm的bit0为1,则跳转时自动将CPSR中的标志T置位,即把目标地址的代码解释为Thumb代码,如果为bit0位为0的话,则跳转时自动将CPSR中的标志T复位,即把目标地址的代码解释为ARM代码。

      (3)再次进行编译后,出现如下错误:

              

      显示“memcpy”的错误,原因是出在init.c文件中的sdram_init2函数上。

    3. 打开init.c文件

       找到init_init2函数后,进行如下修改:

     1 void sdram_init2(void)        /* 没有任何输出,推断这里应该是位置无关的 */  /* 这个函数并不会修改这个数组,它只是把这些值拷贝到寄存器里边去,∴可以加一个const*/
     2 {
     3     const static unsigned int  arr[] = {            // 使用static静态变量,静态变量就会放在数据段里,最终重定位时,
     4         0x22000000,        //BWSCON                            会把值从数据段中拷贝到arr[]数组多对应的地址去
     5         0x00000700,        //BANKCON0                
     6         0x00000700,        //BANKCON1                
     7         0x00000700,        //BANKCON2                在学习Thumb指令时,编译器用到memcpy函数导致make出错,原因是∵这些值肯定是保存在代码里边的,为了构造这个数组,
     8         0x00000700,        //BANKCON3                编译器把这些代码段里值拷贝到arr[]这个局部变量里。
     9         0x00000700,        //BANKCON4
    10         0x00000700,        //BANKCON5
    11         0x18001,        //BANKCON6
    12         0x18001,        //BANKCON7
    13         0x8404f5,        //REFRESH, HCLK=12MHZz: 0x008e07a3, HCLK=100MHz: 
    14         0xb1,        //BANKSIZE
    15         0x20,        //MRSRB6
    16         0x20,        //MRSRB7
    17         };
    18     volatile unsigned int *p = (volatile unsigned int *)0x48000000;
    19     int    i;
    20 
    21     for ( i=0;  i<13; i ++ )
    22     {
    23         *p = arr[i];
    24         p ++;
    25     }
    26     
    27 }

    最后,通过ls -l进行查看生成的.bin文件的大小。

                     

    使用Thumb指令后,

                    

    4. 看反汇编代码

      前边地址仍然是4字节相加,        

                    

      其他指令除bl仍为4字节外,其他指令均变为2字节增长。    

                    

    总结:

      如果Flash空间比较小的话,可以使用Thumb指令集,但对于ARM系统、Linux系统,Flash 空间一般以M为单位,不需要省那么点空间。所以后续使用很少。

  • 相关阅读:
    内存映射文件点滴
    [Buzz.Today]“估摸”手机:Google收购摩托罗拉
    QT程序中的事件处理
    又是一个开始
    HTTP 协议基础
    深入理解HTTP消息头
    HTTP请求模型和头信息
    十个让你变成糟糕的程序员的行为
    获取上层调用函数地址的代码
    MIME类型大全
  • 原文地址:https://www.cnblogs.com/JmZd/p/8810870.html
Copyright © 2020-2023  润新知