这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 测试测量 » 工科谈艺术!mips 编程的艺术!~

共3条 1/1 1 跳转至

工科谈艺术!mips 编程的艺术!~

高工
2011-06-13 09:24:23     打赏
(转)
析系统调用的实现时看到这么一段代码,令人不禁拍案叫绝。

系统调用的参数传递,前4个参数通过a0~a3传,后面的参数要通过栈来传,目前内核
系统调用最长的参数个数为8。

用栈传递参数时,涉及到要将位于用户空间的参数先复制到内核空间(内核栈)。

因为系统调用的参数个数不定,因此就需要判断参数个数为5、6、7、8 不同情况时,
相应的复制操作个数。5个参数时需要复制个数为1,6个时为2,以此类推。

通常的解决方法是用switch语句,这个编译出来,得要四条分支判断语句吧

看看内核的一些牛人怎么实现:



la t1, 5f # 标号5所示之地址入t1
subu t1, t3 # t3 的内容为当前系统调用参数个数减去5,再乘以4
# 这个已经预先计算好,保存于系统调用表每项的第二个
# 字段,用时直接载入。
# 另外,此前已经判断过,t3 的内容大于等于0

1: lw t5, 16(t0) # t0 的内容为用户空间第一个参数的地址

.set push
.set noreorder
.set nomacro

jr t1
addiu t1, 6f - 5f # 妙用分支延迟槽

2: lw t8, 28(t0) # 取用户空间第8个参数
3: lw t7, 24(t0) # 取用户空间第7个参数
4: lw t6, 20(t0) # 取用户空间第6个参数
5: jr t1
sw t5, 16(sp) # 第5个参数进入内核栈

C: sw t8, 28(sp) # 第8个参数进入内核栈
B: sw t7, 24(sp) # 第7个参数进入内核栈
A: sw t6, 20(sp) # 第6个参数进入内核栈
6: j stack_done # 参数复制完毕,返回
nop


只用两条 jr 指令,效率大大提高!简直妙不可言!

下面详细分析之:

(1) t3 的值,在参数个数为5 时,t3 为0,6 时为4,7 时为8,8 时为12
这个 t3 在这里,实际上是用来表示相对于标号5处的地址偏移! 因为mips/godson下,
指令的长度都是4个字节。因此 t3 值为4(参数个数为6)时,第一个 jr t1 是跳转到
标号4处开始执行的。

(2) 第一个 jr t1 用来解决从用户空间复制数据操作的个数问题,相对应的,则是解决写入
操作的个数问题,这个用第二个 jr t1 来解决。在此之前,更新 t1 的指令(addiu)的
位置放的很巧妙,置于第一个 jr t1 的延迟槽中,不占用标号4与标号5之间的空间。

(3) 可以看到参数个数为5时,第二个 jr t1 直接跳转到标号6处执行,将第5个参数写入内
核栈的操作置于延迟槽中;参数个数为6时,会跳转到标号A处执行;参数个数为8时,会
跳转到标号C处执行,依次完成第5、8、7、6参数的写入。


结论:

该段程序的作者对MIPS平台下的延迟槽有深刻的理解,故而才能有如此神乎其技的妙用。



关键词: 工科     艺术     编程     参数     个数    

菜鸟
2011-06-13 09:45:27     打赏
2楼
顶艺术!

高工
2013-03-24 18:13:27     打赏
3楼
这个还是需要点mips架构的基础才能够理解

共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]