arm汇编 调用linux中断,linux arm汇编 - 难点FAQ

1. ARM不支持除法

一个简单的C除法语句可能编译不过,如int c = a/b ; 或int c = a%b,都会报错。

提示:

undefined reference to `__divsi3'

GNU内部使用__divsi3函数来替代ARM下的除法运算,此函数定义在libgcc.a中。本来gcc应该是默认

找这个库的,但由于在命令行中使有的arm-linux-ld(因为要使用-T选项),所以要手工为之指定

arm工具链的libgcc.a。

$(LD) -Tlink.lds -o $@

$^ /code/arm/libgcc.a

经测试只有把libgcc.a的实际路径放在命令行的所有object的后面(位置敏感)才好使。另外,用-lgcc

指定也可以,但也是要求必须放在最后面。

$(LD) -Tlink.lds -o $@ $^ -lgcc -L/code/arm

2. 'not enough room for program headers'

这是一个很复杂的错误,通常是由于在链接脚本里没指定.rodata段来导致的。

ENTRY(start)

SECTIONS

{

. =0x30000000;

.text : { *(.text) }

.data : {*(.data) }

.bss : {*(.bss) }

.rodata :{*(.rodata) }

}

3. AXD在加载elf文件时可能会失败,提示如下:

DBE Warning 00255: WIN32

exception code 0xc0000005 was caught in

dbess_image\dbt_image.cpp:160

网上说,这是由于AXD对高版本的gcc支持不好的原因。例如,在用4.3.2版本编译时,elf文件无法加载。

(1) . 应该换成2.95.3版本(但此版本的gcc不支持c99语法,郁闷)

(2) .

检查是否有未声明的函数调用,尽量使用规矩的方式。例如,调用一个printf(),则最后在前加上该函数的proto-type

(3) 修改设置后,要重启板子、重启AXD再试试

(4) 寄存器变量不可简写

u32 _2440irq_check_srcpnd(u32 index)

{

return rSRCPND &

BIT_VALUE(index);

}

改成

u32 _2440irq_check_srcpnd(u32 index)

{

u32 value = rSRCPND; return value &

BIT_VALUE(index);

}

(5) 板子在启动的时候可能已经运行了程序,这时再进行调试,可能会受到板子上正在运行的程序的影响。

所以可以先做一个简单的程序,用H-Flasher烧写到板子上。这个程序简单到只有一个无限循环。

_reset_handler:

b .

4. 中断向量表的随意跳转

中断向量表是4*8个字节 = 8个向量,如果在每个向量放置B指令跳转的话,由于B指令只能跳转到前后32M的

地址,所以跳转能力有限。所以中断向量一段这么做的:

.section

VectorTable,"x" 0000 ldr pc,

ResetAddr 0001 ldr pc,

UndefinedAddr 0002 …… 0003 …… 0004 …… 0005 …… 0006 …… 0007 …… 0008 ResetAddr: .word

HandlerReset 0009 UndefinedAddr: .word

HandlerUndefined 0010 …… 0011 …… 0012 …… 0013 …… 0014 …… 0015 ……

第0000行,ldr指令把内存在[ResetAddr]的一个字取出来,存到PC;而[ResetAddr]处存放的正是

处理函数Handler的地址。因为arm在进入异常时已经到返回值存到LR里了,所以用ldr pc,...的方式

跳转是没有问题的,处理结束后可以返回来。

(用bl跳转时自动将返回地址存入LR,异常发生时ARM自动将返回地址存到LR)

5. 注意libgcc.a要跟编译器的版本一致

6. 无效的地址可以加载,但不能运行

例如,板子有效的内存地址是0x30000000 -

0x34000000,但是如果指定起始地址为0x60000000也可以加载。

只是运行的时候会提示无法运行。

DBT Warning 00135: Cannot set breakpoints in literal pools

7. 编译器

(1) Friendly Arm带的2.95.3有问题,从网上下载了一个2.95.3可以用,可以接受-gdwarf-2选项

(2) 如果使用2.95.3编译器,需要加上-gdwarf-2选项;如果使用3.4.1,则使用-g即可

(3) elf转成binary

$ arm-linux-objcopy -O binary xxx.elf xxx.bin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值