HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Filling a memory segment with a bit pattern

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
bitwithsegmentfillingmemorypattern

Problem

I want to fill a memory segment with a certain byte pattern using powerpc assembly:

# Task: Fill the area from 0x8000 to (inclusive) 0x8FFF with 0x55 (per byte read/write)

# Write start address - 1 into a register
addis r2, r0, 0x0000
ori r2, r2, 0x7FFF

# Bit pattern is 0x55
addi r3, r0, 0x55

# Size of memory segment + 1
addis r4, r0, 0x0000 
ori r4, r4, 0x1000
# Move that length to CTR register
mtctr r4

loop:
#Write pattern from r3 into the address (1 + r2), and write the result of 1 + r2 back into r2
stbu r3, 1(r2)
# decrement CTR and see if we have reached the end of the segment
bdnz

Solution

You have some unnecessary comments. For example, this comment:

# Move that length to CTR register
mtctr r4


Anyone who knows this instruction set should be easily able to know what that line is doing.

Comments are supposed to explain why, not how because "how" is very easy to find out on one's own.

You did not specify what assembler you were using, but if your assembler allows for creating macros, I recommend that you make macros for those "random" numbers that are in your code.

These "random" numbers are called magic numbers; they've just appeared out of no-where.

In the NASM assembler, you can do something like this:

%define BIT_PATTERN 0x55


Then, in the line where you are working with the bit pattern, you write:

addi r3, r0, BIT_PATTERN


And now there is no confusion about where that number came from and you can remove that comment from above this line.

You should see if you can create macros for this bit pattern like I showed you, and for the memory segment addresses.

Note: I could not find a PowerPC assembler any where on the internet so my recommendations from here on may be slightly flawed in some places.

These lines can be simplified:

addis r2, r0, 0x0000
ori r2, r2, 0x7FFF


All you seem to be trying to do here is stick the value 0x7FFF into the register r2. However, you are taking two instructions to do this:

-
Move 0 into r2

-
Make r2 become 0x7FFF with ori

This seems a little unnecessary; why can't you just put 0x7FFF into r2 to begin with, like you did when you put the bit pattern into r3? A much simpler way of writing this would be:

li r2, 0x7FFF


which is directly equivalent to

addi r2, 0, 0x7FFF


Note: This assumes that r0 was 0 to being with, which I think it was.

The above will put the value 0x7FFF into r2. You can do this same thing for when you are putting the size of the memory segment into r4, and when you are putting the bit pattern into r3.

It didn't look like you specifically needed to actually use the addis instruction, which seems unnecessarily complicated for simply putting a value into a register.

However, if you did, just change the instruction to:

lis r2, 0x7FFF


You are using the registers incorrectly.

According to this page, the registers r2, r3, and r4 are for the table of contents pointer, the return of a function/subroutine, and (commonly) a function/subroutine argument, respectively.

I think you should be using the register r4 through r10 because, since you are not using a subroutine, these registers can now be used for general purpose. You might be okay with using r3, but you definitely should not be using r2.

Putting it all together:

li r4, 0x7FFF
li r5, 0x55
li r6, 0x1000

mtctr r6

loop:
    stbu r5, 1(r4)
    bdnz


If you notice any bugs, notify me.

Code Snippets

# Move that length to CTR register
mtctr r4
%define BIT_PATTERN 0x55
addi r3, r0, BIT_PATTERN
addis r2, r0, 0x0000
ori r2, r2, 0x7FFF
li r2, 0x7FFF

Context

StackExchange Code Review Q#96764, answer score: 3

Revisions (0)

No revisions yet.