So the material on addressing modes may be length and scattered
You will have to scavenge the material on addressing modes by skimming verious parts of the book/manual...
I have done this for the SPARC....
The programmer must write a "small program" (several instructions) to get variables from memory.
In fact, you can say that the programming is "implementing" the address modes with simple instructions - this is called "micro programming".
By "clear cut", I mean, in M68000, you can see exactly what addressing mode is used by looking at one single instruction.
In SPARC, you may need multiple instructions to obtain the operand... which can be quite confusing...
Syntax: add %r1, %r2, %r3 add %r1, constant, %r3 (-212 <= constant <= 212-1) Effect: r3 = r1 + r2 r3 = r1 + constant Examples: Instruction Effect =========== ============== add %i0, %i2, %i3 Reg. i3 = Reg. i1 + Reg. i2 add %i0, %g0, %i2 Reg. i2 = Reg. i1 (because Reg. g0 = 0 !) add %i0, 0, %i2 Reg. i2 = Reg. i1 add %g0, %g0, %i2 Reg. i2 = 0 add %g0, 1, %i2 Reg. i2 = 1Usage of the "add" operation:
Syntax: sethi constant, %r Effect: r = constant * 210 Examples: sethi 0, %i0 +----------+----------+----------+----------+ i0 = | 00000000 | 00000000 | 00000000 | 00000000 | +----------+----------+----------+----------+ sethi 1, %i0 +----------+----------+----------+----------+ i0 = | 00000000 | 00000000 | 00000100 | 00000000 | +----------+----------+----------+----------+ sethi 2, %i0 +----------+----------+----------+----------+ i0 = | 00000000 | 00000000 | 00001000 | 00000000 | +----------+----------+----------+----------+
The "sethi" instruction is used to move the "high" portion of a large constant (such as a memory address) into a register.
The "sethi" instruction is typically followed by a second instruction that completes the lower portion of the constant.
Any (large) constant can be split into 2 half and put back together as follows:
(1) Let large constant be C (2) Find highPortion = C / 1024 (quotient) (3) Find lowPortion = C % 1024 (remainder) (4) Then: C = highPortion*1024 + lowPortion For example: C = 987654 C / 1024 = (quotient) = 964 C % 1024 = (remainder) = 518 Then: 964 * 1024 + 518 = 987654Example:
Move 100000 into register i0: (1) Find highPortion = 100000 / 1024 = 97 (2) Find lowPortion = 100000 % 1024 = 672 We can move 100000 into register i0 in 2 steps: sethi 97, %i0 // Put in the high portion add %i0, 672, %i0 // Add in the low portionMaking SPARC do the calculations of (/ 1024) and (% 1024)
The SPARC assembler has a "built-in" calculator that can compute the division and remainder by 1024. %hi(Value) == Value / 1024 %lo(Value) == Value % 1024 Therefore, we can move 100000 into register i0 using: sethi %hi(100000), %i0 // Put in the high portion add %i0, %lo(100000), %i0 // Add in the low portionExample: move an address into a register
Labels are nothing more than a symbolic name for a number, they are in fact numbers.... huge numbers (32 bits). Hence, we can use the same old technique (of splitting big numbers up) to move (copy) addresses into a register: Let X be a label, like: X: .... We can move the address of X into a register by: sethi %hi(X), %i0 // Put in the high portion add %i0, %lo(X), %i0 // Add in the low PORTion
Syntax: ld [%r1 + %r2], %r3 ld [%r1 + constant], %r3 (-212 <= constant <= 212-1) Effect: "ld [%r1 + %r2], %r3" loads the word (a word is 32 bits in SPARC) from the memory address that is equal to the sum of the values in register r1 and r2, into the register r3 So, if r1 = 1000 and r2 = 16, then the word (32 bits) at memory address 1016 is moved into register r3 "ld [%r1 + constant], %r3" loads the word from the memory address that is equal to the sum of the values in register r1 and the constant, into register r3The main usage of "ld" is to follow "sethi" to move data from a memory location into a register. Because a memory address is 32 bits, SPARC cannot specify the address with 1 instruction and need to break the load instruction into 2 instructions.
Examples: move the value in the integer variable X into register i0
sethi %hi(X), %l0 // Puts high part of addr X // in local reg l0 add %l0, %lo(X), %l0 // Add in the low part of addr X // Now local reg l0 = address value of X ld [%l0 + 0], %i0 // Move the integer value from memory // at the addr given by l0 + 0 (= addr X) // into reg i0We can do better: again, move the value in the integer variable X into register i0
sethi %hi(X), %l0 // Puts high part of addr X // in local reg l0 ld [%l0 + %lo(X)], %i0 // Move the integer value // from memory at the addr // given by l0 + %lo(X) // into reg i0 // ... Since l0 = %hi(X), we have // that l0 + %lo(X) = addr X !!!
Syntax: st %r3, [%r1 + %r2] ld %r3, [%r1 + constant] (-212 <= constant <= 212-1) Effect: "st %r3, [%r1 + %r2]" stores (copies) the word (a word is 32 bits in SPARC) from register r3 to the memory location with the address that is equal to the sum of the values in register r1 and r2 So, if r1 = 1000 and r2 = 16, then the word (32 bits) from r3 is copied to memory location starting at 1016 "st %r3, [%r1 + constant]" stores the word from register r3 into the memory location with the address that is equal to the sum of the values in register r1 and the constantThe main usage of "st" is to follow "sethi" to move data from a register to memory. Because a memory address is 32 bits, SPARC cannot specify the address with 1 instruction and need to break the store instruction into 2 instructions.
Examples: move the value in register i0 to the integer variable X
sethi %hi(X), %l0 // Puts high part of addr X // in local reg l0 add %l0, %lo(X), %l0 // Add in the low part of addr X // Now local reg l0 = address value of X st %i0, [%l0 + 0] // Move the 32 bit value from reg i0 to // memory at the addr given by l0 + 0 // (= addr X)We can do better: again, move the value in the integer variable X into register i0
sethi %hi(X), %l0 // Puts high part of addr X // in local reg l0 st %i0, [%l0 + %lo(X)] // Move the integer value // from rge i0 to memory starting // at the addr given by l0 + %lo(X) // ... Since l0 = %hi(X), we have // that l0 + %lo(X) = addr X !!!