.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
I can understand everything, I think, except how the two instructions andi
and ori
work in this case. ori appears to make so that the ASCII 20 positions forward is printed but why and how?
andi
with 0x7f removes the most significant bit, which is not used by ASCII (which only uses 7 bits, or 0-128 to maps characters). 0x7f is 0111 1111 in binary. Since anything AND with 0 (the most significant bit is 0, as you can see) is 0, anything AND with 1 stays the same, the operation removes the most significant bit.
ori
with 0x20 will only set the 6th bit (25). 0x20 is 0010 0000 in binary. Since anything OR with 1 (the 6th bit, as you can see) is 1, and anything OR with 0 stays the same, it results in setting the 6th bit.
As the comment says, just in case r16 originally is less than 32, or in case r16 >= 128 and < 160, it will make the number >= 0x20. It doesn't mean that it will always add 0x20, though (e.g. r16 originally is 32 --addi--> 33 --andi--> 33 --ori--> 33).
As side note, AND'ing with a constant (which is also called mask) is usually for extracting certain bit out of the original data. And it will extract at whichever bit that the corresponding bit in the mask is 1.
OR'ing with constant is usually for set certain bit(s) to 1. It will set the bit whose corresponding bit in the mask is 1.
By the way, to set certain bit to 0, you can AND with constant that is all 1 except the bit that you want to set. To toggle certain bits, you can XOR with the constant with corresponding bit 1 and the rest 0.
Using and
in assembly is a way to ensure a bit is off. Consider:
1101 and
0111
---------
0101
Only in the second and the last columns do the 1s exist in the top AND
the bottom, effectively ensuring that the first bit is turned off.
Using 'or' in assembly is a way to ensure that a bit is on. consider:
1101 or
0111
----------
1111
The 1s on the bottom row ensure that no matter what the first number is, the last three bits will be on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With