04. Code addressing: conditionals, loops and arrays
(unfinished before)
.align and the meaning of alignment
(reprise) Addressing:
- Direct — no use for jumps (6 bit is not enough)
- Immediate — «near» jumps (relative addresses)
- Indirect — address in register + immediate offset, slower a little
- Type J — «almost as far» jumps (absolute addresses)
Labels
- Address as number is meaningless
You need to recalculate all addresses every time you change code
- Calculate jumps is not easy because of pseudoinstructions
⇒ Assembly lables: TODO example of data labels using in syscalls and loads/stores.
Multiplication and division
Using hi and lo when multiplying, mult vs. mul
Using hi and lo when dividing
mfhi, mflo
Multiplication implementation
- No multiplication / dividing in MIPS-1
We can sll
⇒ n*m = sum(n<<k) for k in non-zero bits position of m!
- ⇒ fixed-timed multiplication (but slow)
Fixtime multiplication:
001101012 * 011100102
001101012=0*27+0*26+1*25+1*24+0*23+1*22+0*21+1*20
a*2b == a<<b (i. e. sll register register b)
⇒ 001101012 * 011100102 =
00110101 * 01110010 ---------- 01110010 00000000₀ 01110010₀₀ + 00000000₀₀₀ 01110010₀₀₀₀ 01110010₀₀₀₀₀ 00000000₀₀₀₀₀₀ 00000000₀₀₀₀₀₀₀ --------------- 001011110011010
Conditionals
Full table in documentation
- No arithmetic operations in single conditional
- ⇒ sign, zero and equality instructions only
⇒ lesser / greater are pseudoinstructions
- No need in 0 and 1 bit (they're always =0)
- Forward jumps — conditionals
- Backward jumps — loops
A bit of theory: canonical loop flow:
Initialization
condition Check
- (assembler language) jump outside (4)
Body
conditional variables Update
- (assembler language) jump to (2)
Why two jumps (alternative: final check and jump into)?
An example:
See compiled code:
Relative address count starts from next word.
- Relative address can be negative
All addresses /= 4 (strictly speaking >>=2 ☺ )
Nested loops
- No magic
- Keep an eye on register usage
- The meaning of initialization
TODO: multimplication tablecolumn
Arrays
Array: a number of identical type data objects placed together in memory
- ⇒ Array[i] = address(Array) + len(Array data type)*i
- ⇒ We can use indirect addressing!
1 .data 2 Array: .space 40 # 40 bytes of memory 3 .word 0xdeadbeef # this is just for pointing out array end 4 5 .text 6 li $t0 10 # counter initialization 7 la $t1 Array # la is full equivalent of li, it just declares another semantic 8 loop: blez $t0 final # condition check 9 sw $t0 ($t1) # Array[i] = 10-i 10 addiu $t1 $t1 4 # Add 4 to address 11 addiu $t0 $t0 -1 # Update counter 12 b loop 13 final: li $v0 10 # stop 14 syscall
- 40 bytes = 10 words
- integer array: i+=1 ⇒ address+=4
using of la
H/W
EJudge: DigitSum 'Sum of digits'
Input an integer (can be negative), and output sum of its' digits.
-12345
15
EJudge: PlusMinus 'Plus and Minus'
Input a cardinal N, then input N integers ai; output the result of a0-a1+a2-…±aN-1 .
4 22 13 14 15
8
EJudge: EvenBack 'Even backwards'
Input a cardinal N, then N integers. Output line by line only even ones, in reversed order.
6 12 -11 3 88 0 1
0 88 12
Input a cardinal N, then N integers. Output all the integers, skipping duplicated ones.
8 12 34 -12 23 12 -12 56 9
12 34 -12 23 56 9