3878|9

65

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

问个ARM中C语言和汇编程序的简单问题? [复制链接]

copy_2th_to_sdram  主要用来将第二部分的代码(led驱动操作相关的),从steppingstone中复制到SDRAM中,在连接程序时,第二部分代码的加载地址被指定为2048,重定位地址为0xB0004000。所以系统从nand flash启动后,第二部分代码就存储在steppingstone中地址2048之后,需要把它复制到0x30004000处(MMU开启之前,VA(0xB0004000)==PA(0x30004000))。Steppingstone总大小为4KB,我们将2048之后的所有数据复制到SDRAM中,所以源数据结束地址就为4096。
/*  
* 将第二部分代码复制到SDRAM  
*/  
void copy_2th_to_sdram(void)   
{   
    unsigned int *pdwSrc  = (unsigned int *)2048;   
    unsigned int *pdwDest = (unsigned int *)0x30004000;   
      
    while (pdwSrc < (unsigned int *)4096)   
    {   
        *pdwDest = *pdwSrc;   
        pdwDest++;   
        pdwSrc++;   
    }   
}
想问下为什么0x30004000前面还要加(unsigned int *),0x30004000已经代表地址了啊;
还有汇编程序里像
.text   
.global _start

.align 4
这样子的为什么加个点,.align 4 又是什么意思呢,新手不是很理解,哪位说下?
此帖出自ARM技术论坛

最新回复

学习了~  详情 回复 发表于 2009-12-29 14:55
点赞 关注
 

回复
举报

81

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
友情帮顶下。!
此帖出自ARM技术论坛
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
.text 部分是处理器开始执行代码的地方.
.global关键字用来让一个符号对链接器可见,可以供其他链接对象模块使用。.global _start 让 _start 符号成为可见的标识符,这样链接器就知道跳转到程序中的什么地方并开始执行。
此帖出自ARM技术论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

4
 
0x30004000只是个立即数。前面加(unsigned int *),表示把它强转成指针,另外表示它指向的是unsigned int类型的数据。
此帖出自ARM技术论坛
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

5
 
楼上说得对0x30004000只能是数,强制转换的目的是把它转换成相应形式的指针,如果不这么作有些编译器会出警告,而有些编译器会认为是个错误。

align 4
应该是四字节对齐的意思,也就是说这段数据的起始地址是4的整数倍,如0x00000018,0x00000020,如果不做这样的修饰,编译器可能会为了节省内存而使用连续空间的形式接着前边数据的地址,导致下边的数据地址是0x00000011
此帖出自ARM技术论坛
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

6
 
当你上位机和下位机通讯时,你就能理解四字节对齐了:)
此帖出自ARM技术论坛
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

7
 
引用 4 楼 veabol 的回复:
楼上说得对0x30004000只能是数,强制转换的目的是把它转换成相应形式的指针,如果不这么作有些编译器会出警告,而有些编译器会认为是个错误。

align 4
应该是四字节对齐的意思,也就是说这段数据的起始地址是4的整数倍,如0x00000018,0x00000020,如果不做这样的修饰,编译器可能会为了节省内存而使用连续空间的形式接着前边数据的地址,导致下边的数据地址是0x00000011

up
此帖出自ARM技术论坛
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

8
 
再问个问题,在ARM环境下,
unsigned long virtuladdr;
unsigned long *mmu_tlb_base = (unsigned long *)0x30000000;
virtuladdr = 0xA0000000;
(virtuladdr >> 20))  = 0xA00

(mmu_tlb_base + (virtuladdr >> 20))  = 0x30000000 +0xA00 *4 :之所以乘4,是由于mmu_tlb_base 是unsigned int指针
0x30000000 +0xA00 *4  = 0x30002800
(mmu_tlb_base  + 1)的实际结果是mmu_tlb_base 的地址值加上4

我想问下为什么要乘以4,在同样的环境下,改为unsigned int 类型指针时,是不是要乘以2,
unsigned char类型指针时,是不是要乘以1???C基础不是很好,但希望不要再叫我翻书或者Baidu了,要是我看书百度一下子明白就不会问这么简单的问题了,呵呵,再次谢谢你们,希望再回答下,分不够可以加的话你说,麻烦了~
此帖出自ARM技术论坛
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

9
 
unsigned long *mmu_tlb_base = (unsigned long *)0x30000000;
如果执行mmu_tlb_base=mmu_tlb_base+1,会得到mmu_tlb_base为0x30000004的结果,对于指针的加减操作会将+1自动转换为+指针类型字节数
(unsigned short *)mmu_tlb_base+1的结果是0x30000002
(unsigned long)mmu_tlb_base+1的结果是0x30000001

long指针是4字节对齐,所以+1实际上地址等于+4
short指针是2字节对齐,所以+1实际上地址等于+2
long指针是1字节对齐,所以+1实际上地址等于+1

int不同编译器针对不同硬件平台会得出不同结果,有可能是32位(4字节),也有可能是16位(2字节)


----------------------------------

将一个立即数的值传给指针前必须加(long *)这样的强制转换是C语言为了防止误操作采取的一种保护措施,不同指针有不同的对齐要求,虽然立即数可以表示出地址的具体数值,但存在一个问题:有可能给一个不满足对齐要求的值给long这样有对齐要求的指针,这样会出错,如果语法上要求必须强制转换,可以提醒程序员在该位置留意转换的对齐问题
此帖出自ARM技术论坛
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

10
 
学习了~
此帖出自ARM技术论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表