[SPARC] 位处理运算

问题定义


位处理运算

想要实现对存储 0 63 的数字集合的运算。集合在静态区域中以 set1、 set2、set3 的名称定义。 set1、set2、set3 的每一位代表 63、62、 ... 、2、1、0,如果对应 的数字属于该集合,则该位指定为 1 ,否则为 0 起初只需定义用于测试的集合。

  • member(j, set): 如果 j set 的元素,则返回 1

  • union: 并集。 set3 = set1 set2

  • intersection: 交集。 set3 = set1 set2

  • subtract: 差集。 set3 = set1 - set2

  • add(j, set): 在集合 set 中添加元素 j

  • mapinc(set,d): 集合 set 中每个元素加上 d 后的集合。 例如 set({1, 13, 17}, 1) = {2, 14, 18}

    提交物

  • 提交仅定义了上述 3 个函数的文件。 不提交定义了 main 和集合 set1、set2 的文件。 各自用于测试时,需单独创建并链接使用。


设计

1. 集合在静态区域中以 set1、set2、set3 的名称定义。
2. set1、set2、set3 的每一位代表 63、62、61....、2、1、0。
3. 如果对应的数字属于该集合,则该位指定为 1,否则为 0。
4. 定义初始测试集合。

< 不起眼的源代码.. >

1. member(j,set) 函数 > 结果 0 或 1

*如需运行相应源代码,请取消 粗体注释 </span> </span> </span> </div>

!.section ".data"

!set1:.word 1 , 4 , 5 , 16

!set2:.word 1 , 4 , 7 , 23

!

!.section ".text"

!!local variables

!n = -4


! index i in $l0

! max in $l1

! .global main

!main : save %sp, -96 ,%sp

! set set1, %l2

!    st %l2,[%sp + 16 ]

! set set2, %l3

!    st %l3,[%sp + 32 ]

!    mov 16 ,%o0

!    call member

!    mov %l2,%o1

!test : ret

! restore


!N= 4 ! ( if N = 4 , it 's only works in {a,b,c,d} just 4 objects)

.global member

member : save %sp, -96 ,%sp

mov 1 ,%l0 ! move 1 to l0

sll %l0,N,%l5 ! 2 ^N to l5 (this time 2 ^ 4 = 16 )

add %fp,%l5,%o3 ! address %fp +16

ld [%o3],%o0 ! right value of [%fp +16 ]

cmp %i0,%o0 ! x == [%fp +16 ] ?

be,a isexist ! if yes goto isexist return

ba loop ! or not goto loop

indexup : inc %l0 ! increase index ++

loop:   sll %l0, 2 ,%l2 ! address l2 = i* 4

add %o0,%l2,%o1 ! [%fp +16 +i* 4 ]

ld [%o1],%l1    ! load [%fp +16 +i* 4 ]

cmp %i0,%l1     ! x== [%fp +16 +i* 4 ]

be isexist      ! if equal then goto isexist

cmp %l0,N       ! %l0 < N

bl,a indexup    ! if true goto indexup

nop

nonexist: mov 0 ,%i0 ! return value 0 - not exist

ret

restore

isexist: mov 1 ,%i0 ! return value 1 - it 's exist

ret

restore



2. add(j,set) 函数 >  { 1,3,4, j }

*如需运行相应源代码,请取消 粗体注释 </span> </span> </span> </div>

!.section ".data"

!set1:.word 1 , 4 , 5 , 16

!

!.section ".text"

!local variables

!n = -4

!

! index i in $l0

! max in $l1

!

! .global main

!main : save %sp, -96 ,%sp

! set set1, %l2

!    mov 44 ,%o1

!    call add

!    mov %l2,%o0

!test : ret

! restore

!N= 4 ! ( if N = 4 , it 's only works in {a,b,c,d} just 4 objects)

.global add

add :    save %sp, -96 ,%sp

mov 1 ,%l0

mov %i0,%o0 ;

sll %l0,N,%l5 ! 2 ^N to l5 (this time 2 ^ 4 = 16 )

add %i0,%l5,%i0

st %i1,[%i0]

addend:     ret

restore

</div>

3. mapinc(set,d) 函数 >  {1,3,4} , d= 1 > {2,4,5}

*如需运行相应源代码,请取消 粗体注释 </span> </span> </span> </div>

!.section ".data"

!set1:.word 1 , 4 , 5 , 16

!set2:.word 1 , 4 , 7 , 23

!

!.section ".text"

!local variables

!n = -4

!

! index i in $l0

! max in $l1

!

! .global main

!main : save %sp, -96 ,%sp

! set set1, %l2

!    st %l2,[%sp + 16 ]

!    mov 1 ,%o1

!    call mapinc

!   mov %l2,%o0

!test : ret

! restore

!

!N= 4 ! ( if N = 4 , it 's only works in {a,b,c,d} just 4 objects)

.global mapinc

mapinc :    save %sp, -96 ,%sp

mov 1 ,%l0

sll %l0,N,%l5 ! 2 ^N to l5 (this time 2 ^ 4 = 16 )

add %fp,%l5,%o3 ! address %fp +16

ld [%o3],%o0 ! right value of [%fp +16 ]

ba loop ! or not goto loop

clr %l0

indexup :   inc %l0 ! increase index ++

loop:       sll %l0, 2 ,%l2 ! address l2 = i* 4

add %o0,%l2,%o1 ! [%fp +16 +i* 4 ]

ld [%o1],%l1    ! load [%fp +16 +i* 4 ]

add %l1,%i1,%l1 ! add  %l1 = %l1 + %i1

st %l1,[%o1]    ! store %l1 to [%fp +16 +i* 4 ]

cmp %l0,N       ! compare %l0 < N

bl,a indexup    ! if true goto indexup

nop

ret

restore




不起眼的源代码已经全部结束了...
在做这次作业的过程中,我感觉到访问数组地址时如果使用位处理,就不需要另外使用 mul 来计算地址了。非常方便。
当然,代码并没有经过优化。因为我还是个超级菜鸟..

大概花了 6 个小时在捣鼓这些代码上。通过调试逐一确认了内存中存储的内容。

啊,调试时使用的命令是..

- gcc -g main.c -o main     ::  将 main.c 文件编译为 global 标签可引用的文件,并生成名为 main 的可执行文件。

- gdb main   :: 调试 main。

- p $i0    ::  输出 %i0,即 i0 寄存器的值。
- p set1   ::  查看静态变量 set1 到第 n 个值。
ex) -p set1    >> {1 , 4 , 5 }


我对内容的理解可能有很多错误之处。如果能指正,我会进行修正。
谢谢。

</div> </div> </div> </div>
AD