第十三课(3)汇编文件里的拷贝代码和链接脚本的改进

1、改进拷贝代码

cpy:
	strb r4, [r1]
	ldrb r4, [r2]
	add r1, r1, #1
	add r2, r2, #1
	cmp r2, r3
	bne cpy
	
	/* 清除bss段 */
	mov r0, #0
	ldr r1, =bss_start
	ldr r2, =bss_end
	
clean:
	strb r0, [r1]
	add r1, r1, #1
	cmp r1, r2
	bne clean

上面代码的不足之处:
JZ2440上的Nor Flash是16位,SDRAM是32位。
假设现在需要复制16byte数据,
采用ldrb命令每次只能加载1byte,因此CPU需要发出16次命令,内存控制器每次收到命令后,访问硬件Nor Flash,因此需要访问硬件16次;
同理,访问SDRAM时,CPU需要执行strb 16次,内存控制器每次收到命令后,访问硬件SDRAM,也要16次。
这样总共访问32次。
改进:
现在对其进行改进,使用ldr从Nor Flash中读,ldr命令每次加载4字节数据,因此CPU只需执行4次,但由于Nor Flash是16位的,内存控制器每次收到CPU命令后,需要拆分成两次访问,因此需要访问硬件8次;
使用str写SDRAM,CPU只需执行4次,内存控制器每次收到命令后,直接硬件访问32位的SDRAM,因此这里只需要4次,这样总共访问只需要12次。

ble Branch if Less than or Equal

cpy:
    ldr r4, [r1]
    str r4, [r2]
    add r1, r1, #4 //r1加4
    add r2, r2, #4 //r2加4
    cmp r2, r3 //如果r2 =< r3继续拷贝
    ble cpy

/* 清除BSS段 */ 
    ldr r1, =bss_start
    ldr r2, =bss_end
    mov r3, #0
clean:
    str r3, [r1]
    add r1, r1, #4
    cmp r1, r2 //如果r1 =< r2则继续拷贝
    ble clean

    bl main

运行结果:
发现启动后没有输出字符。修改主程序,尝试以整数格式输出字符:

#include "s3c2440_soc.h"
#include "uart.h"
#include "init.h"

char g_Char = 'A';
char g_Char3 = 'a';
const char g_Char2 = 'B';
int g_A = 0;
int g_B;

int main(void)
{
	uart0_init();

	puts("\n\rg_A = ");
	printHex(g_A);
	puts("\n\r");

	while (1)
	{
		puts("\n\rg_Char = ");
		printHex(g_Char);
		puts("\n\r");
		
		puts("\n\rg_Char3 = ");
		printHex(g_Char3);
		puts("\n\r");
		
		putchar(g_Char);
		g_Char++;

		putchar(g_Char3);
		g_Char3++;
		delay(1000000);
	}

	
	return 0;
}

2、改进链接脚本

烧写运行,发现输出的数从0开始,应该是全局变量被破坏了:
运行结果:
g_Char = 0x00000000

g_Char3 = 0x00000000

g_Char = 0x00000001

g_Char3 = 0x00000001

g_Char = 0x00000002

g_Char3 = 0x00000002

我们先把清除bss段的代码屏蔽了,发现就能正常输出.
说明可能是清除bss段的时候,把全局变量也清除了
查看下反汇编文件:
bss_start = 30000002
bss_end = 3000000c
str 0 [ 30000002 ]
str是以4字节存放入30000002地址,但是30000002不是4字节对齐的地址,
所以会变成str 0 [ 30000000 ]
从反汇编文件可以看出,30000000是数据段的起始地址

Disassembly of section .data:

30000000 <data_start>:
30000000:	41          	.byte	0x41

30000001 <g_Char3>:
30000001:	61          	.byte	0x61
Disassembly of section .bss:

30000004 <g_A>:
30000004:	00000000 	.word	0x00000000

30000008 <g_B>:
30000008:	00000000 	.word	0x00000000

那么我们修改链接脚本,让地址向4向上取整:

SECTIONS {
   .text   0  : { *(.text) }
   .rodata  : { *(.rodata) }
   .data 0x30000000 : AT(0x800) 
   { 
		data_start = . ;
		*(.data) 
		data_end = . ;
   }
   data_load_addr = LOADADDR(.data);
   
   . = ALIGN(4);
   bss_start = .;
   .bss  : { *(.bss) *(.COMMON) }
   bss_end = .;
}

查看反汇编代码,可以看到我们的bss段为30000004

Disassembly of section .data:

30000000 <data_start>:
30000000:	41          	.byte	0x41

30000001 <g_Char3>:
30000001:	61          	.byte	0x61
Disassembly of section .bss:

30000004 <g_A>:
30000004:	00000000 	.word	0x00000000

30000008 <g_B>:
30000008:	00000000 	.word	0x00000000
Disassembly of section .ARM.attributes:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值