CS-A1120 Programming 2
Department of Computer Science
Aalto University
(Based on material by Petteri Kaski and Tommi Junttila)
armlet assembly languageConsider the following sequential logic circuit:
where denotes the operation XOR (exclusive or).
111010.
What are the updated bit values (as read left to right) after the circuit has been clocked one time, that is at \(t = 1\)?
Binary representation of data (here, an 8 bit bus)
Combinational logic
Combinational logic
Combinational logic
Sequential logic, for state
Takes care of calculations and logic in a computer processor
ALU = Arithmetic Logic Unit
$0 … $7 are registers, internal stateimmed_in allows data inputoperation encodes which operation to performL, A, B are destination (L) and source registers (A, B)Sequential logic also allows us to retain state, and build a memory
Internally, each memory word retains its state (e.g. using feedback) until it is updated by a write)
A memory module is circuit of multiple one-word memories that can be addressed (indexed)
mem_addr is the memory address busmem_read_e and mem_write_e control reading/writing on that addressmem_data and read_out are the input/output busesmem_addr size \(n\) can hold \(2^n\) words of data
operation, L, A, B (total 16 bits = one word), and if needed immed_in (16 bits)Boooring (and slow) - let's get the machine to automatically read the next instruction
(Armlet is an example of a von Neumann architecture)
(How does the processor know when to stop executing?)
In principle, we can program a computer by setting bits in memory corresponding to the instructions we want the processor to execute
| Armlet Machine code(s) | Armlet assembly | High-level language |
0111000010000111 |
sub $2, $0, $7 |
r2 = r0 - r7 |
0000001011011100 0011000000111001 |
ior $3, $1, 12345 |
r3 = r1 | 12345 |
Solved?
A programmable machine can, with right programming, simulate another programmable machine
armlet):var's (the registers) and one huge array (the memory)Always, do it but especially in this round!
var t = 10 var i = 1 var s = 0 while t != 0 do s = s + i i = i + 1 t = t - 1 // Now the sum is in 's'
mov $0, 10 # $0 = 10 mov $1, 1 # $1 = 1 mov $2, 0 # $2 = 0 @loop: # This is a label cmp $0, 0 # $0 == 0 ? (PS) beq >done # if PS is eq add $2, $2, $1 # $2 = $2 + $1 add $1, $1, 1 # $1 = $1 + 1 sub $0, $0, 1 # $0 = $0 - 1 jmp >loop # Jump back @done: # Another label hlt # Stop, sum in $2
mov $0, 10 # $0 = 10 mov $1, 1 # $1 = 1
mov moves a value to a register
add $1, $1, 1 # $1 = $1 + 1 sub $0, $0, 1 # $0 = $0 - 1
add and sub adds and subtracts, respectively.
mov $1, 7 add $2, $1, 3
What are the value of $1, and $2 after these instructions?
@done: on a line will have the assembler associate that memory address with the label 'done' jmp >target # jump to label @target
# ... some code here ...
@target:
# ... some further code here ...
(Note that you can jump both forwards and backwards in the code)
What is the value in $1 after this code is executed (starting from the top)?
mov $1, 18 # $1 = 18 add $1, $1, 2 # $1 = $1 + 2 jmp >next # Jump mov $2, 10 # $2 = 10 sub $1, $1, $2 # $1 = $1 - $2 @next: sub $1, $1, 5 # $1 = $1 - 5 hlt # Stop
# ... code # ... code # ... code # ... code cmp $0,0 # compare, this sets PS beq >done # branch this sets PC # ... code - This will # ... code - only be # ... code - done # ... code - if $0 != 0 @done: # Start here if $0 == 0
mov $0, 10 # $0 = 10 mov $1, 1 # $1 = 1 mov $2, 0 # $2 = 0 @loop: # This is a label cmp $0, 0 # $0 == 0 ? (PS) beq >done # if PS is eq add $2, $2, $1 # $2 = $2 + $1 add $1, $1, 1 # $1 = $1 + 1 sub $0, $0, 1 # $0 = $0 - 1 jmp >loop # Jump back @done: # Another label hlt # Stop, sum in $2
if r7 != 0 then do <some code here> else do <and more code here>
(Think about: if does one or the other, branching can do a combination of them depending on other instructions.)
cmp updates the Processor Status registercmp callcmp and the branch instruction!
What's the value in $0 after this code is executed (starting from the top)?
mov $0, 3 # $0 = 3 @start: cmp $0, 2 # Compare val. in $0 to 2 sub $0, $0, 1 # $0 = $0 - 1 bne >start # Branch if last cmp != hlt # Stop
loa and sto can be used to move words between memory and registersloa x,y is x = mem(y), and sto x,y is mem(y) = x.)
(In armlet PC always starts at 0, so data usually comes after program.)
This program loads a value from memory, increases it by 10, and writes it back to the same memory location:
mov $0, >myDataStart # Put address of data to $0 loa $1, $0 # $1 = value at address in $0 add $1, $1, 10 # Increase value in $1 by 10 sto $0, $1 # Store the value in $1 to address in $0 hlt # Stop @myDataStart: %data 5, 6
(After executing the value at the address indicated by @myDataStart is 15, the next one is 6.)
This program loads a value from memory, increases it by 10, and writes it to the memory address two words further:
mov $0, >myDataStart # Put address of data to $0 loa $1, $0 # $1 = value at address in $0 add $1, $1, 10 # Increase value in $1 by 10 add $0, $0, 1 # Update the address in $0 by 1 sto $0, $1 # Store the value in $1 to address in $0 hlt # Stop @myDataStart: %data 5, 6
(After executing the value at the address indicated by @myDataStart is 5, the next one is 15.) The reason is the call add $0, $0, 1 which moves the address in $0 one word forward.
sto $1, $0 instead we would have written the value in $0 to address 15 (the content of $1)
What are the values in $1, $2, and $3 after this code is executed (starting from the top)?
mov $0, >myDataStart # Put address of data to $0 loa $1, $0 # $1 = value at address in $0 add $0, $0, 1 # Increase address loa $2, $0 # $2 = value at address in $0 add $0, $0, 2 # Increase address loa $3, $0 # $3 = value at address in $0 hlt @myDataStart: %data 5, 6, 7, 8, 9, 10
# Computes (to $0) the sum of the data and then halts.
# Let us first set things up ...
mov $0, 0 # the sum starts with 0
mov $2, >length_of_my_data # set up memory address where to get length
loa $2, $2 # load the length from memory to $2
mov $1, >my_data # set up memory address where to get the data
# Now let us loop through the data and accumulate the sum ...
@sum_loop:
cmp $2, 0 # compare length with 0
beq >done # ... branch to label @done if $2 == 0
loa $3, $1 # load a data item from memory
add $0, $0, $3 # accumulate the sum in $0
add $1, $1, 1 # advance to next data item
sub $2, $2, 1 # decrement length by one
jmp >sum_loop # continue the summation
# ... until we are done
@done:
hlt # the processor stops here
# Our data follows the program code in the binary ...
@length_of_my_data:
%data 20
@my_data:
%data 296, 573, 291, 415, 825, 674, 426, 632, 793, 701, 884, 1, 989, 912, 254, 869, 462, 296, 767, 220
(%data is a directive - an assembly helper tool; %data 20 will translate the literal 20 to binary and write it as data to memory)
More examples in the course notes
$0, $1, $2 when execution halts?
mov $0, 18 mov $1, 15 cmp $0, $1 blt >labA mov $2, $0 jmp >labB @labA: mov $2, $1 @labB: lsl $2, $2, 1 hlt
| instruction | what it does |
|---|---|
blt X |
Jump to X if left < right (in prev. cmp) |
cmp $A, $B |
Compare A and B |
hlt |
Halt execution |
jmp X |
Jump (go to) X |
lsl $L, $A, $B |
L = A << B (left shift) |
mov $L, I |
L = A |
Comment your code!
Run the program launchTicker.scala in the armlet sub-project.
But, it is hard work as a programmer…
(Comment your code!)
How can two program run simultaneously? How can a program wait for input? Print output? How are high level programs translated into machine code?
Work through the notes examples first, these contain a lot of useful code!
failure: string matching...)