.global main # makes label "main" globally known
.text # Instructions follow
.align 2 # Align instructions to 4-byte words
main: movi r16,0x47 # Load the hexadecimal value 41
# to register r16
loop: mov r4,r16 # Copy to r4 from r16
nop # (later changed to call hexasc)
nop # (later changed to mov r4,r2)
movia r8,putchar # copy subroutine address to a register
callr r8 # call subroutine via register
addi r16, r16,1 # Add 1 to register r16
andi r16, r16, 0x7f # mask with 7 bits
ori r16, r16, 0x20 # set a bit to avoid control chars
br loop # Branch to loop
.end # The assembler will stop reading here
foo bar bletch # comes after .end - ignored
我认为,除了两个说明andi
和ori
在这种情况下的工作原理之外,我能理解所有内容。 ori似乎是为了打印ASCII 20位置,但为什么以及如何?
答案 0 :(得分:4)
andi
删除最高有效位,ASCII不使用它(仅使用7位,或0-128来映射字符)。 0x7f是二进制的0111 1111。由于任何AND与0(最高有效位为0,如您所见)为0,任何AND与1保持不变,操作将删除最高位。
ori
仅设置第6位(2 5 )。 0x20是二进制的0010 0000。因为任何OR与1(第6位,如你所见)是1,任何OR与0保持不变,它会导致设置第6位。
正如评论所说,只是在r16最初小于32的情况下,或者在r16> = 128且< 160,它将使数字> = 0x20。但这并不意味着它总是会添加0x20(例如r16最初是32 --addi - > 33 --andi - > 33 --ori - > 33)。
作为旁注,AND'与常量(也称为掩码)通常用于从原始数据中提取某些位。并且它将提取掩码中相应位为1的任何位。
与常量进行“或”运算通常是将某些位设置为1.它将设置掩码中相应位为1的位。
顺便说一下,要将某个位设置为0,除了要设置的位之外,您可以使用常量除了1之外的常量。要切换某些位,可以使用相应位1的常量进行异或,其余为0。
答案 1 :(得分:2)
andi和ori都是按位运算符:
要看到差异,请使用“
and $rd, $rs, $rt
or $rd, $rs, $rt
与
andi $rt, $rs, immed
ori $rt, $rs, immed
http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Mips/bitwise.html
答案 2 :(得分:2)
在汇编中使用and
是一种确保关闭位的方法。考虑:
1101 and
0111
---------
0101
仅在第二列和最后一列中,1s位于顶部AND
的底部,有效地确保第一位被关闭。
在汇编中使用'或'是确保某个位开启的一种方法。考虑:
1101 or
0111
----------
1111
底行的1s确保无论第一个数字是什么,最后三位都将打开。