Variables in memory and constants
Two words the assembler writes into memory, a constant that never leaves the instruction, and the total written back where you can see it.
Two numbers are written into memory by the assembler and a third one is written into an instruction. The program reads the two out of memory, adds the third, and writes the total back into memory, which is where you read the answer.
Moving values around kept everything in registers, and there are only 32 of those. Anything a
program has more of than that goes in memory, and .word is what puts it there before the first
instruction runs.
You need to know: the ".data, .text and directives" lecture and the "Memory, little endian and
alignment" lecture. What is new here is the difference between a name that is a number and a name
that is an address, TAX is replaced by 20 inside the instruction while price becomes
0x10010000 and the program goes to memory for what is there.
Six instructions where the M68K needs four, and the two extra ones are the whole of what a
load/store architecture means. add.l shipping, d0 on the M68K adds the long at a label straight
into a register; here add only reads registers, so anything in memory arrives through a lw first
and goes back through a sw at the end.
The three words sit at 0x10010000, where .data puts the first label. Type 10010000 in the
memory panel's address box:
| label | address | before | after |
|---|---|---|---|
price | 0x10010000 | FA 00 00 00 | unchanged |
shipping | 0x10010004 | 23 00 00 00 | unchanged |
total | 0x10010008 | 00 00 00 00 | 31 01 00 00 |
.word writes a value, .space 4 only reserves four bytes, which is why total reads as zeroes
before the program runs: unwritten memory reads 0 in this editor. After the run it holds
0x00000131, which is 305, and t1 holds the same number.
The bytes come out backwards from how you would read the number, because RISC-V is little endian and
the lowest byte of a word goes at the lowest address. 250 is 0x000000FA and the panel shows
FA 00 00 00. The W button in the panel's header groups the bytes into words and shows them the
way round you wrote them.
la t0, price is done once and every access after it is an offset from that one register:
0(t0), 4(t0) and 8(t0) are the three words. Writing lw t1, price works too and costs two
instructions every time it runs, an auipc that works the address out and the lw itself, both
into t1. MIPS spends its $at on the same line and RISC-V has no such register, which is also why
a store to a label is written sw t1, total, t2, with a third operand naming the register the
address is built in.
Try changing price: .word 250 to price: .word 500. total comes out at 2B 02 00 00, which is
555, and the only thing that changed is the four bytes the assembler writes at 0x10010000 before
your program starts.