Thursday, 5 January 2017

A PowerPC instruction a day series 3

First POWER5 program explaination


References:

Therefore, since the address can be up to 64 bits, we have to load it a piece at a time (part 2 of this series will show how to avoid this). @-signs within the assembler instruct the assembler to give a specially-processed form of a symbol value. The following are used here:
@highest
refers to bits 48-63 of a constant
@higher
refers to bits 32-47 of a constant
@h
refers to bits 16-31 of a constant
@l
refers to bits 0-15 of a constant

The instruction ld 4, 0(7) loads the value at the address in register 7 into register 4 (the zero means to add zero to that address).             i.e.  ld r4, 0(r7)

Each system call has an associated number. This number is stored in register zero before making the call. The rest of the arguments start in register three, and continue on for however many arguments the system call needs. Then the sc instruction causes the kernel to take over and respond to the request. The system call number for exit is 1. Therefore, the first thing we need to do is to move the number 1 into register 0.

if the specified register is register 0, it doesn't add a register at all, and uses the number 0 instead. This seems confusing, but the reason for it is to allow PowerPCs to use the same instruction for adding as for loading (why?).
he exit system call takes one parameter -- the exit value. This is stored in register 3. Therefore, we need to move our answer from register 6 to register 3. The "register move" instruction rm 3, 6 performs the needed move. Now we are ready to tell the operating system we are ready for it to do its trick.
The instruction to call the operating system is simply sc for "system call". This will invoke the operating system, which will read what we have in register 0 and register 3, and then exit with the contents of register 3 as our return value. On the command line, we can retrieve this value using the command echo $?.
Just to point out, a lot of these instructions are redundant, but used for teaching purposes. For example, since first_value and second_value are essentially constant, there is no reason we can't just load them directly and skip the data section altogether. Likewise, we could have stored the results in register 3 to begin with (instead of register 6), and saved a register move. In fact, we could have used register 3 for both a source and a destination register. So, if we were just trying to be concise, we could have written it like this:
Listing 2. A short version of the first program
.section ".opd", "aw"
.align 3
.global _start
_start:
        .quad ._start, .TOC.@tocbase, 0
.text
        li 3, 1   #load "1" into register 3
        li 4, 2   #load "2" into register 4
        add 3, 3, 4    #add register 3 to register 4 and store the result in register 3
        li 0, 1   #load "1" into register 0 for the system call
        sc


Conclusion

Hopefully, you now have a basic feel for assembly language programming on the PowerPC. The instructions may look a little weird at first, but they will become second-nature with practice. In the next article, I'll cover the various addressing modes of both the PowerPC processor, and how they can be used to do 64-bit programming more effectively. In the third article, we will cover the ABI more fully, discussing what registers are used for what purpose, how to call and return from functions, and other interesting aspects of the ABI.

No comments:

Post a Comment