本文主要是介绍ARM 汇编 伪指令 MACRO及MEND,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
ARM 汇编 伪指令 MACRO及MEND MACRO伪操作标识 宏定义的开始,MEND标识宏定义的结束。 用MACRO 及MEND定义一段代码,称为宏定义体,这样在程序中就可以通过宏指令多次调用该代码段 语法格式 MACRO {$label} macroname {$parameter {,$parameter}...} ;code ... ;code MEND 其中: $labelz在宏指令被展开时,label可被替换成相应的符号,通常是一个标号。在一个符号前使用$标识程序被汇编时将使用相应的值来替代$后的符号 Macroname为所定义的宏的名称 $parameter为宏指令的参数。当宏指令被展开时将被替换成相应的值,类似于函数中的形式参数。可以在宏定义时为参数指定相应的默认值。 MACRO $HandlerLabel HANDLER $HandleLabel $HandlerLabel sub sp,sp,#4 ;decrement sp(to store jump address) stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address) ldr r0,=$HandleLabel;load the address of HandleXXX to r0 ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR) MEND ;;在程序中调用 HandlerFIQ HANDLER HandleFIQ HandlerIRQ HANDLER HandleIRQ HandlerUndef HANDLER HandleUndef HandlerSWI HANDLER HandleSWI HandlerDabort HANDLER HandleDabort HandlerPabort HANDLER HandlePabort 比如第一个为例说明 HandlerFIQ HANDLER HandleFIQ ;;程序被汇编后,宏展开的结果 HandlerFIQ sub sp,sp,#4 stmfd sp!,{r0} ldr r0,=HandleFIQ ldr r0,[r0] str r0,[sp,#4] ldmfd sp!,{r0,pc} 下面一句一句分析一下,为了便于分析,假设sp = 0x33ff8000,$HandleLabel =0x33ffff00, [0x33ffff00] = 0x10000000,r0 = 0x56001234: $HandlerLabel HANDLER $HandleLabel 宏的名字叫HANDLER ,有两个参数 $HandlerLabel 定义一个标号 sub sp,sp,#4 把栈顶指针减4,留出一个字的空间(用于保存跳转地址的值),sp=0x33ff7ffc stmfd sp!,{r0} 首先把sp减4 (sp=0x33ff7ff8),然后把将要使用的r0寄存器入栈,此时[0x33ff7ff8]=0x56001234 ldr r0,=$HandleLabel 给寄存器r0赋值,r0=0x33ffff00 ldr r0,[r0] 给寄存器r0赋值,r0=0x10000000 str r0,[sp,#4] ;把寄存器r0保存到0x33ff7ffc (0x33ff7ff8+4),sp没有改变sp=0x33ff7ff8,如果 str r0,[sp,#4]!sp 改变 此时 ;[0x33ff7ffc] = 0x10000000 ldmfd sp!,{r0,pc} 把栈顶的两个字弹出,分别保存到r0、pc,此时sp=0x33ff8000,r0=0x56001234,pc=0x10000000 ,通过比较不难发现,sp和r0在执行前后都没有变化,程序就跳转到0x10000000处执行 转载出自:http://www.360doc.com/content/10/1101/14/3038654_65704006.shtml |
这篇关于ARM 汇编 伪指令 MACRO及MEND的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!