×
单片机 > 单片机程序设计 > 详情

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

发布时间:2023-06-20 发布时间:
|

在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数组中元素;



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
AVR熔丝位操作时的要点和需要注意的相关事项