查看: 10268|回复: 9

[提问] arm-linux-gcc编译的结果,反汇编出来的入口为什么不正确?

[复制链接]
发表于 2009-6-19 01:56:21 | 显示全部楼层 |阅读模式
关键词: 编译 , 汇编 , 结果 , 入口
.extern    main
.text
.global    _start
@ 0x00: 系统入口,此处放置一条跳转语句,跳过中断向量表,至于中断向量表,实际是最后被copy到SDRAM的高端地址,通过MMU来处理进入
_start:  @-------->这里定义的入口处
    b    real_start  @-------->这里是跳过reset,但是reset实际是存在的,但不是程序真正的开始

@ 0x04: 中断向量表并非从0地址开始放置,因为我们使用的直接SDRAM调试时,中断入口是需要通过MMU来映射的
Reset:
    b    Reset            @直接在SDRAM中调试的话,实际是不使用Reset的,因此一Reset,硬件系统将从nand flash中读取uboot来执行,所以此处实际是个空语句处理


@ 0x08: Undefined instruction exception
HandleUndef:
    b    HandleUndef

@ 0x0c: Software interrupt exception  
HandleSWI:
    b    HandleSWI

@ 0x10: Prefetch Abort (Instruction Fetch Memory Abort)
HandlePrefetchAbort:
    b    HandlePrefetchAbort

@ 0x14: Data Access Memory Abort
HandleDataAbort:
    b    HandleDataAbort

@ 0x18: Not used
HandleNotUsed:
    b    HandleNotUsed

@ 0x1c: IRQ(Interrupt Request) exception
    ldr    pc,HandleIRQAddr

@ 0x20: FIQ(Fast Interrupt Request) exception
HandleFIQ:
    b    HandleFIQ
HandleIRQAddr:   
    .long    HandleIRQ

real_start:   
@here,跳过系统上电后从0地址出的中断向量表开始执行,这是为了不用烧写FLASH来进行调试
@here,此处应该先将系统设置为上电时系统的默认模式,因为此时系统尚运行于uboot的环境

    ldr    sp,    =0x30100000    @设置运行于SDRAM时的堆栈
    bl    disable_watch_dog    @关闭看门狗
    bl    clock_init        @初始化时钟,启动PLL,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz
    bl    memsetup_2        @设置SDRAM
@    bl    init_nand        @SDARM调试,不使用nand flash,所以不用初始化nand 控制器
    bl    copy_vectors_to_high    @此处使用lelee自己的代码,将0x3000 0004地址开始的中断向量表copy到SDRAM的高端去
   


-----------------------------------------------------------
以上为head.s的开头处

00000000 <.data>:
   0:    e1a0c00d     mov    ip, sp
   4:    e92dd800     stmdb    sp!, {fp, ip, lr, pc}
   8:    e24cb004     sub    fp, ip, #4    ; 0x4
   c:    e3a02313     mov    r2, #1275068416    ; 0x4c000000
  10:    e3e034ff     mvn    r3, #-16777216    ; 0xff000000
  14:    e5823000     str    r3, [r2]
  18:    e3a03313     mov    r3, #1275068416    ; 0x4c000000
  1c:    e2833014     add    r3, r3, #20    ; 0x14
  20:    e3a02003     mov    r2, #3    ; 0x3
  24:    e5832000     str    r2, [r3]
  28:    ee111f10     mrc    15, 0, r1, cr1, cr0, {0}
  2c:    e3811103     orr    r1, r1, #-1073741824    ; 0xc0000000
  30:    ee011f10     mcr    15, 0, r1, cr1, cr0, {0}
  34:    e3a02313     mov    r2, #1275068416    ; 0x4c000000
  38:    e2822004     add    r2, r2, #4    ; 0x4
  3c:    e3a03917     mov    r3, #376832    ; 0x5c000
  40:    e2833040     add    r3, r3, #64    ; 0x40
  44:    e5823000     str    r3, [r2]
  48:    e89da800     ldmia    sp, {fp, sp, pc}
  4c:    43434700     cmpmi    r3, #0    ; 0x0
  50:    4728203a     undefined
  54:    2029554e     eorcs    r5, r9, lr, asr #10
  58:    2e342e33     mrccs    14, 1, r2, cr4, cr3, {1}
  5c:    00000031     andeq    r0, r0, r1, lsr r0
  60:    eafffffe     b    0x60  @---->这里是中断入口了
  64:    eafffffe     b    0x64
  68:    eafffffe     b    0x68
  6c:    eafffffe     b    0x6c
  70:    eafffffe     b    0x70
  74:    eafffffe     b    0x74
  78:    e59ff000     ldr    pc, [pc, #0]    ; 0x80
  7c:    eafffffe     b    0x7c
  80:    300040c4     andcc    r4, r0, r4, asr #1
  84:    e59fd04c     ldr    sp, [pc, #76]    ; 0xd8

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

很纳闷,不知道为什么突然边成这样了,之前都还是好好的,反汇编的开始处是中断入口

谁给个答案?小弟谢谢了

发表于 2009-6-19 13:22:09 | 显示全部楼层
呵呵,没怎么理解清楚楼主的问题

0x18应该为IRQ的入口吧怎么会是:

@ 0x18: Not used
HandleNotUsed:
    b    HandleNotUsed
发表于 2009-6-19 13:30:05 | 显示全部楼层
传说中的一式三招,ls...
发表于 2009-6-19 13:30:18 | 显示全部楼层
传说中的一式三招,ls...
 楼主| 发表于 2009-6-19 18:39:29 | 显示全部楼层
南哥,我在连接的时候,直接把程序全放在0x30004000处了,直接通过uboot下载到SDRAM中去跑,而不是每次都烧写nand,所以在程序的最开始处,相当于中断向量表中的Reset的位置放置了一条跳转指令b    real_start 来跳过reset,而真正的中断向量表是往后推了4个字节来,所以那个保留的未使用的存放地址就到了0x18了,我的程序里边用了段代码将b    real_start后边的7个word空间的向量表copy到SDRAM的高地址去了(这样应该是可以进中断的吧?中断的进入只与pc的值和存放位置有关,与编译连接应该没什么关系吧?)

我的问题是,为什么编译的结果,0地址的b    real_start和紧接着的中断向量表不在最开始处,而是跑到了“60:    eafffffe     b    0x60  @---->这里是中断入口了”这里来了?

昨天改程序,改来改去,编译结果还是这样,反汇编出来的代码就是一楼里贴的,而且下载到SDRAM里了,根本不跑
 楼主| 发表于 2009-6-19 18:45:49 | 显示全部楼层
本来弄了个简单的,不开中断的 程序,在main()里边的while(1)中用led的交替亮灭来测试,是正常的(就是连接直接指明程序从30004000处开始运行,编译结果用uboot下载到30004000处,然后go 30004000,是可以正常跑的。MMU也开了,64M的SDRAM的地址空间,除了33f0 0000映射到ffff 0000处(33f0 0000开始存放中断向量表),其他地址都是映射为本身,寄存器也一页映射为本身地址)
但是加了timer0后,编译的结果就成这样了,莫名其妙
发表于 2009-6-22 09:05:09 | 显示全部楼层
其实问题没有考虑太多.但是有一点必需清楚的认识到,CPU复位之后PC指向0x0地址,产生IRQ时PC指向0x18,这是三星ARM处理器的铁的实事.就是俺是中国人一样永远是改变不了的事实!
发表于 2009-6-22 09:06:10 | 显示全部楼层
其实问题没有考虑太多.但是有一点必需清楚的认识到,CPU复位之后PC指向0x0地址,产生IRQ时PC指向0x18,这是三星ARM处理器的铁的实事.就是俺是中国人一样永远是改变不了的事实!
 楼主| 发表于 2009-6-24 22:53:53 | 显示全部楼层
2410中断入口有两中摆放方式嘛,低端和高端
如果放高端的话,复位后PC指向FFFF0000吧
IRQ来的时候就指向FFFF0018了吧
发表于 2011-1-14 10:12:08 | 显示全部楼层
居然有人这种问题都没有搞懂
发表于 2011-1-14 10:12:28 | 显示全部楼层
0x18就是未用嘛
 楼主| 发表于 2011-1-14 12:04:06 | 显示全部楼层
LS弄明白到底时什么问题了么?!:-)

讨论的是反汇编的结果不正确,正常反汇编出来的结果不是这样

至于0X18用没用,压根没提到过,并且是把程序入口重新映射了,并且用链接脚本处理过

弄明白了再跟贴
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表