Addr
0000000 main: # Start of program
0000100 #
0001000 # There would be code
0001100 # leading up to this fragment...
0010000 #
0011100 #
0011000 LP: slt $t1, $s0, $s1 # $t1 = 1 if $s0 < $s1
0011100 beq $t1, $zero, ENDLP #
0100000 #
0100100 # ... lots of stuff here
0101000 #
0101100 #
0110000 j LP # jump back to top of LP
0110100 ENDLP: #
0111000 #
0111100 # ... more code follows the loop
1000000 #
1000100 #
Label | Instruction Address |
---|---|
main | 00...0000000 (0) |
LP | 00...0011000 (24) |
ENDLP | 00...0110100 (52) |
The label is replaced with a value computed from the address, rather than the address directly.j LP
becomes the machine code equivalent ofj 24/4
000010 000000...0000110
24 / 4 = 6beq $t1, $zero, ENDLP
becomes the machine code equivalent ofbeq $t1, $zero, (52-PC)/4
000100 01000 00000 0000000000000101
(52-32)/4 = 5
|
|
|
|
|
|
|
|
|||||||||||||||||||||||
1000 | 1004 | 1008 | 100C | 1010 | 1014 | 1018 | 101C |
How would you know where each (label, address) pair starts?
Ptr to Label Name | Instruction Address | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
1000 |
|
|
typedef struct { char * labelName; int address; } LabelEntry; |
|||||||
1008 |
|
|
||||||||
1010 |
|
|
||||||||
… | ||||||||||
… | ||||||||||
1410 |
|
|||||||||
1415 |
|
|||||||||
1418 |
|
|
|
|
|
|
|
||||||
1000 | 1008 | 1010 | |||||||||
… | |||||||||||
… |
|
|
|
||||||||||||||||
1410 | 1415 | 1418 |
(The strings might, or might not, be laid out contiguously in memory like this.)