免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1145 | 回复: 0
打印 上一主题 下一主题

看程序学习arm汇编指令 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-05 20:21 |只看该作者 |倒序浏览

今天找了个简单的函数跟一下
void NVODTimerReset()
{
    UINT8 i;
    for(i = 0;i   {
        if(nvodTimerContent.timer_mode!=TIMER_MODE_OFF)
        {
            nvodTimerContent.timer_mode = TIMER_MODE_OFF;
        }
    }
}
数据说明:
#define MAX_NVOD_TIMER_NUM 8
#define TIMER_MODE_OFF 0
TIMER_SET_CONTENT nvodTimerContent[MAX_NVOD_TIMER_NUM];
typedef struct{
UINT8 timer_mode;
UINT8 timer_service;
UINT16 wakeup_year;
UINT8 wakeup_month;
UINT8 wakeup_day;
UINT32 wakeup_time;
UINT16 wakeup_duration_time;
UINT8 wakeup_chan_mode;
UINT32 wakeup_channel;
UINT8 wakeup_message;
UINT8 wakeup_state;
} TIMER_SET_CONTENT;

对应函数NVODTimerReset()的汇编:
//先把sp的值保存到r12
0x00045260 :  mov     r12, sp  
//把 pc+8,lr,r12,r11中的值依次入栈,db表示在传送前地址减1(这样就指向了栈顶的第一个空元素),pc+8->sp-1,lr->sp-5,r12->sp-9,r11->sp-13.并将sp中的值更新为新的栈顶sp-17(放完了r11的四个字节)指向存放r11的最后一个字节单元         
0x00045264 :  stmdb   sp!, {r11, r12, lr, pc}  
//把r12中的值减4送入r11,相当于r11中的地址值就是上一条命令存入内容的最后一个字节地址.            
0x00045268 :  sub     r11, r12, #4    ; 0x4   
//把sp中的地址往栈顶上移四个字节出来            
0x0004526c : sub     sp, sp, #4      ; 0x4  
//为i赋初值0               
0x00045270 : mov     r3, #0  ; 0x0
//先保存i的值。r11减13后刚好是存放完stmdb指令中r11的栈顶第一个空地址值 
0x00045274 : strb    r3, [r11, #-13]  
//取出i的值         
0x00045278 : ldrb    r3, [r11, #-13] 
//i
0x0004527c : cmp     r3, #7; 0x7   
//上面判断结果是大于,则跳出循环                     
0x00045280 : bhi     0x452e0   
//继续循环,首先保存出循环跳转需要的指令地址到r1   
0x00045284 : ldr     r1, [pc, #88]   ; 0x452e4  
//取数组元素是这样一个原理:根据数组下标index来计算数组元素到数组起始地址的偏移,在把该偏移加上数组起始地址就得到了需要取出元素的地址。此处,结构体的大小是24个字节,因此在计算偏移值的时候是把index的值乘上24的,指令中把24拆分成移位运算。先看取值的第一条指令
//把index即i的值读入r2   
0x00045288 : ldrb    r2, [r11, #-13] 
//再把r2放入r3           
0x0004528c : mov     r3, r2
//把r3左移移位,即把i值乘上2
0x00045290 : mov     r3, r3, lsl #1
//将乘上2后和乘2前的i相加,即是把i乘上3
0x00045294 : add     r3, r3, r2
//在上面的基础上把i左移3位,即又乘上了8,前前后后就乘上了24,刚好等于结构体(四字节对齐)的大小
0x00045298 : mov     r3, r3, lsl #3
//最后把数组起始地址与偏移值相加,得到需要取出元素地址值
0x0004529c : add     r3, r3, r1  
//从地址里取出数组元素值                           
0x000452a0 : ldrb    r3, [r3] 
//把取出的值与TIMER_MODE_OFF(0)比较               
0x000452a4 : cmp     r3, #0  ; 0x0 
//上面比较结果相等,则跳转            
0x000452a8 : beq     0x452d0  
//上面比较结果不等,保存需要跳转用的指令地址到r1     
0x000452ac : ldr     r1, [pc, #48]   ; 0x452e4
//这里就和上面取值是一个道理了     
0x000452b0 : ldrb    r2, [r11, #-13]                        
0x000452b4 : mov     r3, r2
0x000452b8 : mov     r3, r3, lsl #1
0x000452bc : add     r3, r3, r2
0x000452c0 : mov     r3, r3, lsl #3
//把要赋值的数组元素的地址保存到r2
0x000452c4 :        add     r2, r3, r1   
//把TIMER_MODE_OFF(0)放入r3                  
0x000452c8 :        mov     r3, #0  ; 0x0  
//把r3的值保存到r2中地址对应的存储单元,即为数组成员赋值       
0x000452cc :        strb    r3, [r2]   
//取出保存的循环计数i                    
0x000452d0 :        ldrb    r3, [r11, #-13]  
//执行i++       
0x000452d4 :        add     r3, r3, #1      ; 0x1   
//保存自加后的i  
0x000452d8 :        strb    r3, [r11, #-13] 
//无条件跳转到0x45278,重新进行i的判断后循环       
0x000452dc :        b       0x45278   
0x000452e0 :        ldmib   sp, {r11, sp, pc}
0x000452e4 :      addeqs  r6, r12, r12, lsl #25


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/94690/showart_1919084.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP