当前位置: 技术问答>linux和unix
ARM栈操作问题?
来源: 互联网 发布时间:2017-04-23
本文导语: ;*********************************************************************** ; 软中断处理 ;*********************************************************************** IMPORT do_led_on IMPORT do_led_off HandleSWI STMFD SP!, {R0-R12, LR} ; 保存程序执行现场 LDR R4, ...
;***********************************************************************
; 软中断处理
;***********************************************************************
IMPORT do_led_on
IMPORT do_led_off
HandleSWI
STMFD SP!, {R0-R12, LR} ; 保存程序执行现场
LDR R4, [LR, #-4] ; LR - 4 为指令" swi xxx" 的地址,低24位是软件中断号
BIC R4, R4, #0xFF000000 ; 取得ARM指令24位立即数
CMP R4, #1 ; 判断24位立即数,如果为1,调用do_led_on系统调用
LDREQ LR, =swi_return ; 软中断处理返回地址
LDREQ PC, = do_led_on ; 软中断号1对应系统调用处理
CMP R4, #2 ; 判断24位立即数,如果为2,调用do_led_off系统调用
LDREQ LR, =swi_return ; 软中断处理返回地址
LDREQ PC, = do_led_off ; 软中断号2对应系统调用处理
MOVNE R0, #-1 ; 没有该软中断号对应函数,出错返回-1
swi_return
LDMIA SP!, {R0-R12, PC}^ ; 中断返回, ^表示将spsr的值复制到cpsr
想问下高手们,LDR R4, [LR, #-4] 这里的R4的改变 会不会影响栈里面的R4,如果是MOVNE R0, #-1 我就懂了, 如果不是 那么这里怎么解释MOVNE R0, #-1, R0改变了么? 我确实有些糊涂了 关于ARM的栈的操作 劳烦老师们,同仁帮帮忙,
; 软中断处理
;***********************************************************************
IMPORT do_led_on
IMPORT do_led_off
HandleSWI
STMFD SP!, {R0-R12, LR} ; 保存程序执行现场
LDR R4, [LR, #-4] ; LR - 4 为指令" swi xxx" 的地址,低24位是软件中断号
BIC R4, R4, #0xFF000000 ; 取得ARM指令24位立即数
CMP R4, #1 ; 判断24位立即数,如果为1,调用do_led_on系统调用
LDREQ LR, =swi_return ; 软中断处理返回地址
LDREQ PC, = do_led_on ; 软中断号1对应系统调用处理
CMP R4, #2 ; 判断24位立即数,如果为2,调用do_led_off系统调用
LDREQ LR, =swi_return ; 软中断处理返回地址
LDREQ PC, = do_led_off ; 软中断号2对应系统调用处理
MOVNE R0, #-1 ; 没有该软中断号对应函数,出错返回-1
swi_return
LDMIA SP!, {R0-R12, PC}^ ; 中断返回, ^表示将spsr的值复制到cpsr
想问下高手们,LDR R4, [LR, #-4] 这里的R4的改变 会不会影响栈里面的R4,如果是MOVNE R0, #-1 我就懂了, 如果不是 那么这里怎么解释MOVNE R0, #-1, R0改变了么? 我确实有些糊涂了 关于ARM的栈的操作 劳烦老师们,同仁帮帮忙,
|
明白你说的了,你是想在调用软中断后希望返回出错码是吗?
LDMIA SP!, {R0-R12, PC}^,确实会把事先放入R0中的-1这个出错码覆盖掉。
那么建议就用一个全局静态变量来保存这个出错码,从软中断返回后,去读这个全局静态变量,来使用可以解决这个问题。
或者LDMIA SP!, {R0-R12, PC}^改一下,LDMIA SP!, {R1-R12, PC}^,但是返回后,SP就有个偏移量了,这个可以调用一个修正SP的汇编方式编写的函数,不过有隐患(如果在修正SP之前,中断来了就会导致SP和栈中数据错乱),不推荐。
希望像调用函数获取返回值的方式来得到软中断的出错码本身就不是很好,毕竟函数流程确实还是和软中断流程有差异的。
|
LDR R4, [LR, #-4] 这里的R4的改变不会影响栈里面的R4,STMFD SP!, {R0-R12, LR}这条指令已经把R4中的值保存到栈中了,现在只是暂时用一下R4,以后在需要用到原来R4中的值时,弹栈即可。
在立即数中判断软中号的方式我是知道的,但是具体的代码没去弄过,一般物品都是用的R0来传递软中号。你这里使用的立即数方式传递软中号,我也不知道对不对。看了注释感觉像是对的。
用立即数方式传递软中号,只能是低24位。
LDR R4, [LR, #-4] 把触发当前软中断的指令取出到R4中。
BIC R4, R4, #0xFF000000 把高位清零,剩下的就是软中断号了。
剩下的不解释了,注释已经很清楚了,如果是因为对指令本身不熟悉,那么自己上网查查相关的指令吧,这几个指令很常见也很简单。
最后LDMIA SP!, {R0-R12, PC}^是和之前STMFD SP!, {R0-R12, LR}相对的弹栈指令,这里注意带了个^,表示把SPSR同时恢复到CPSR中,这也就是回到软中断之前的那个状态了。
你问的栈操作是哪里不明白呢?
在立即数中判断软中号的方式我是知道的,但是具体的代码没去弄过,一般物品都是用的R0来传递软中号。你这里使用的立即数方式传递软中号,我也不知道对不对。看了注释感觉像是对的。
用立即数方式传递软中号,只能是低24位。
LDR R4, [LR, #-4] 把触发当前软中断的指令取出到R4中。
BIC R4, R4, #0xFF000000 把高位清零,剩下的就是软中断号了。
剩下的不解释了,注释已经很清楚了,如果是因为对指令本身不熟悉,那么自己上网查查相关的指令吧,这几个指令很常见也很简单。
最后LDMIA SP!, {R0-R12, PC}^是和之前STMFD SP!, {R0-R12, LR}相对的弹栈指令,这里注意带了个^,表示把SPSR同时恢复到CPSR中,这也就是回到软中断之前的那个状态了。
你问的栈操作是哪里不明白呢?