1

NOTE: I post the latest version of my code below:

I have been volunteered to modify some inherited PowerPC 565 assembler.

I want to pass values in and out from/to Ada code.

I have defined two globals and can – sort of – access on in assembler.

lis     r29, %hiadj(My_INPUT)     # get the address of MY_INPUT - high
addi    r29, r29, %lo(MY_INPUT)   # " - low

lwz     r25, 0(r29)               # copy high contents to r25
lwz     r26, 4(r29)               # copy low  contents to r26 (should that 4 be 8?)

but, what I get in r25 and r26 is the address of MY_INPUT. When I view that memory address, I see the contents that I expect to see – the value of MY_INPUT.

Question: how do I get the value of MY_INPUT (which is a 64 bit value) into a register.

Bonus: how do I move the contents of a register into the global MY_OUTPUT?

I know that book recommendations are off-topic theses days. So, although that would be my preferred question, I won’t ask it :-)


[Update] I am looking for an example which takes a value form one global, increment it and store it to a second global.

Here's what I have:

VC_INPUT : System.INTEGER_32; pragma import(Convention => Assembler, Entity => VC_INPUT, External_Name => "VC_INPUT"); pragma volatile (VC_INPUT);

VC_OUTPUT : System.INTEGER_32; pragma import(Convention => Assembler, Entity => VC_OUTPUT, External_Name => "VC_OUTPUT"); pragma volatile (VC_OUTPUT);

.global VC_INPUT
.global VC_OUTPUT

.bss

VC_INPUT:   .space 4    # size in bytes
VC_OUTPUT:  .space 4

and

# OK, we will take the globalVC_INPUT , add 1 and return it in VC_OUTPUT
lis     r29, %hiadj(VC_INPUT)     # get the address of VC_INPUT - high
addi    r29, r29, %lo(VC_INPUT)   # " - low
lwz     r19, 4(r29)               # get VC_INPUT value    

# OK, we will take the input global, add 1 and return it in VC_OUTPUT 
addi    r19, r19, 1               # increment it by one
lis     r23, %hiadj(VC_OUTPUT)    # get the address of VC_OUTPUT - high
addi    r23, r23, %lo(VC_OUTPUT)  # " - low   
stw     r19, 4(r23)               # write incremented value to VC_OUTPUT

First point, I do not understand why I had to offset by 4 in

`lwz     r19, 4(r29)               # get VC_INPUT value`

What actually happens is that I set VC_INPUT to 0x12345678, and the code sets VC_OUPUT to 0x1234567812345679.

Close, but no cigar. What am I doing wrongly? Please either correct my code, or provide a better example.

Mawg says reinstate Monica
  • 38,334
  • 103
  • 306
  • 551
  • 2
    Code looks sane. Maybe it's Ada that's storing your global with indirection. – Jester Jan 18 '19 at 11:59
  • Thanks for the confirmation. Can you tell me how to get the value from that address into a register (and vice-versa)? I can't find any good tutorials or books. – Mawg says reinstate Monica Jan 18 '19 at 12:02
  • 1
    I think inserting an `lwz r29, 0(r29)` in the middle empty line should do it. – Jester Jan 18 '19 at 12:06
  • 1
    Look at C compiler output for a tiny function that dereferences an `int **p` or whatever. https://godbolt.org/ has PowerPC gcc and clang installed, see [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116) for more about using it. `lwz` loads a 32-bit word (zero-extending to a 64-bit register). Unless you actually *need* the final address in a register, you'd normally use `%lo(MY_INPUT)` as the displacement in a load, I think. (You can always do that on MIPS, but I'm not 100% sure that PowerPC loads have as many immediate bits as `addi`) – Peter Cordes Jan 18 '19 at 12:06
  • @Jester D'oh!! That did the trick, of course. Care to post an answer, to help others who read this in future? And, while you are at it, you might also give an example of writing from a register to a global variable ;-) – Mawg says reinstate Monica Jan 21 '19 at 09:27
  • @PeterCordes the bounty is expiring - care to answer? – Mawg says reinstate Monica Jan 27 '19 at 18:13

0 Answers0