ARM重定向代码字节对齐问题

在ARM学习过程中,用到代码的重定向,链接脚本中字节不对齐时碰到的问题,具体初始化代码如下

1、链接脚本

SECTIONS
{
       . = 0xD0020010;
       .text : {
              start.o
              * (.text)
       }
       .data : {
              * (.data)
       }
       bss_start = .;
       .bss : {
              * (.bss)
       }
       bss_end = .;
}

2、这段代码的主要功能是将代码拷贝到指定的连接地址运行,

.global _start
_start:
       adr r0,_start
       ldr r1,=_start
       ldr r2,=bss_start
       cmp r0,r1
       beq clean_bss
 
copy_loop:
       ldr r3,[r0],#4
       str r3,[r1],#4
       cmp r1,r2
       bne copy_loop
 
clean_bss:
       ldr r0,=bss_start
       ldr r1,=bss_end
       cmp r0,r1
       beq run_on_dram
       mov r2,#0
clean_loop:
       str r2,[r0],#4
       cmp r0,r1
       bne clean_loop
 
run_on_dram:
       ldr pc,=main
halt:
       b halt
 

3、主函数

char c;
int main()
{
       uart0_init();
       while(1)
       {
              c = getc();
              putc(c+1);
       }
       return 0;
}

遇到的问题是加了连接脚本重定向之后程序不能运行了,通过反汇编查处问题所在。

在反汇编代码中看到

  d0020060:      d002027c      andle   r0, r2, ip, ror r2 //bss_start
  d0020064:      d002027d      andle   r0, r2, sp, rorr2//bss_end

bss_end与bss_end竟然只相差一个字节,也就是说bss段只占用了一个字节,bss清0代码为

str r2,[r0],#4

cmp r0,r1 //r0为bss_start,r1为bss_end

每次清0步进为4字节而由于bss段只有一个字节,第一次比较r0,r1时,不相等,执行循环,bss_start地址加4之后清0在比较,由于多加4个字节,因此也不想等,继续加,这样一直循环下去,到只程序在这里执行死循环。

为什么bss段只有一个字节呢?

bss段是放置未初始化的全局变量和静态变量,由于main中使用了一个全局的char c变量,因此只占用一个字节。

解决办法:

最后的解决办法是将charc定义为局部变量,也可以将清0段代码步进改为1,如果在连接文件中使用ALIGN(4)进行字节对齐,当使用char数组是应该注意每一个char均占用了4byte,因此不能用以往占用一个字节的方式读取char数组中元素;

粽子糖果 发表于09-19 10:09 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

粽子糖果
粽子糖果(总统)
金币:41631个|学分:51991个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号