The Assembly Process

Download Report

Transcript The Assembly Process

The Assembly Process
Basically why does it all work
The Assembly Process
•A computer understands machine code - binary
•People (and compilers) write assembly language
Assembly
source code
assembler
Machine code
•An assembler is a program that translates each instruction
to its binary machine code equivalent.
•It is relatively simple program
•A one-to-one or near one-to-one correspondence
between assembly language instructions and machine
language instructions.
•Assemblers do some code manipulation
•Like MAL to TAL
•Label resolution
•A macro assembler can process simple macros like
puts, or preprocessor directives.
MAL  TAL
MAL is the set of instructions accepted by the assembler.
TAL is a subset of MAL – the instructions that can be directly
turned into machine code.
•There are many MAL instructions that have no single TAL
equivalent.
•To determine whether an instruction is a TAL instruction
or not:
•Look in appendix C or on the MAL/TAL sheet.
•The assembler takes (non MIPS) MAL instructions and
synthesizes them into 1 or more MIPS instructions.
MAL  TAL
For example
mul $8, $17, $20
Becomes
mult $17, $20
mflo $8
•MIPS has 2 registers for results from integer multiplication
and division: HI and LO
•Each is a 32 bit register
•mult and multu places the least significant 32 bits of its
result into LO, and the most significant into HI.
•Multiplying two 32-bit numbers gives a 64-bit result
•(232 – 1)(232 – 1) = 264 – 2x232 - 1
MAL  TAL
mflo, mtlo, mfhi, mthi
Move From lo
Move To hi
•Data is moved into or out of register HI or LO
•One operand is needed to tell where the data is coming
from or going to.
•For division (div or divu)
•HI gets the remainder
•LO gets the dividend
•Why aren’t these just put in $0-$31 directly?
MAL  TAL
TAL has only base displacement addressing
So this:
lw $8, label
Becomes:
la $7, label
lw $8, 0($7)
Which becomes
lui $8, 0xMSPART of label
ori $8, $8, 0xLSpart of label
lw $8, 0($8)
MAL  TAL
Instructions with immediates are synthesized with other
instructions
So:
Becomes:
add $sp, $sp, 4
addi $sp, $sp, 4
For TAL:
•add requires 3 operands in registers.
•addi requires 2 operands in registers and one
operand that is immediate.
•In MIPS assembly immediate instructions include:
•addi, addiu, andi, lui, ori, xori
•Why not more?
MAL  TAL
TAL implementation of I/O instructions
This:
putc $18
Becomes
addi
add
syscall
$2, $0, 11
$4, $18, $0
# code for putc
# put character argument in $4
# ask operating system to do a function
MAL  TAL
getc $11
Becomes:
addi
syscall
add
done
Becomes:
$2, $0, 12
$11, $0, $2
puts $13
Becomes:
addi
add
syscall
$2, $0, 4
$4, $0, $13
addi
syscall
$2, $0, 10
MAL  TAL
MAL
TAL
move $4, $3
add $4, $3, $0
add $4, $3, 15
addi $4, $3, 15
# also andi, ori, etc.
mul $8, $9, $10
mult $9, $10
mflo $8
div $8, $9, $10
div $9, $10
#HI || LO  product
# never overflow
# $8  $L0, ignore $HI!
# $LO  quotient
# $HI  remainder
mflo $8
rem $8, $9, $10
div $9, $10
mfhi $8
bltz, bgez, blez, bgtz,
beqz, bnez, blt, bge, bgt,
beq, bne
bltz, bgez, blez, bgtz, beq, bne
MAL  TAL
MAL
TAL
Branches:
beqz $4, loop
beq $4, $0, loop
blt $4, $5, target
slt $at, $4, $5
bne $at, $0, target
# $at is 1 if $4 < $5
# $at is 0 otherwise
I/O instructions:
put, puts, putc, get, getc,
done
Really “procedure call to OS”
Assume $2  call type
Assume $4  input parameters
putc $12
addi $2, $0, 11
add $4, $12, $0
syscall
done
addi $2, $0, 10
syscall
# putc is syscall 11
# see page 262
# char to putc
# call OS
# done is syscall 10
Assembly
The assembler will
•Assign addresses
•Generate machine code
If necessary, the assembler will
•Translate (synthesize) from the accepted assembly
to the instructions available in the architecture
•Provide macros and other features
•Generate an image of what memory must look like for
the program to be executed.
Assembler
What should the assembler do when it sees a directive?
•
•
•
•
•
.data
.text
.space, .word, .byte
org (HC11)
equ (HC11)
How is the memory image formed?
Assembler
Example Data Declaration
a1:
a2:
a3:
.data
.word 3
.byte ‘\n’
.space 5
Address
0x00001000
0x00001004
0x00001008
0x0000100c
Contents
0x00000003
0x??????0a
0x????????
0x????????
•Assembler aligns data to word addresses unless told not to.
•Assembly process is very sequential.
Assembler
Machine code generation from simple instructions:
Assembly language:
addi $8, $20, 15
opcode
immediate
rt
Machine code format:
rs
31
0
opcode
rs
rt
immediate
•Opcode is 6 bits – addi is defined to be 001000
•Rs – source register is 5 bits, encoding of 20, 10100
•Rt – target register is 5 bits, encoding of 8, 01000
The 32-bit instruction for addi $8, $20, 15 is:
001000 10100 01000 0000000000001111
Or
0x2288000f
Instruction Formats
I-Type Instructions with 16-bit immediates
•ADDI, ORI, ANDI
OPC:6
rs1:5
rd:5
immediate:16
•LW, SW
OPC:6
rs1:5 rs2/rd
OPC:6
rs1:5
displacement:16
•BNE
rs2:5 distance(instr):16
Instruction Formats
J-Type Instructions with 26-bit immediate
•J, JAL
OPC:6
26-bits of jump address
R-Type All other instructions
•ADD, AND, OR, JR, JALR, SYSCALL, MULT, MFHI,
LUI, SLT
OPC:6
rs1:5
rs2:5
rd:5 ALU function:11
Assembly Example
a1:
a2:
a3:
main:
loop:
.data
.word
.word
.word
3
16:4
5
.text
la $6, a2
lw $7, 4($6)
mult $9, $10
b loop
done
Assembly Example
Symbol Table
Symbol
a1
a2
a3
main
loop
address
0040 0000
0040 0004
0040 0014
0080 0000
0080 0008
Memory map of data section
address
Contents (hex)
Contents (binary)
0040 0000
0000 0003
0000 0000 0000 0000 0000 0000 0000 0011
0040 0004
0000 0010
0000 0000 0000 0000 0000 0000 0001 0000
0040 0008
0000 0010
0000 0000 0000 0000 0000 0000 0001 0000
0040 000c
0000 0010
0000 0000 0000 0000 0000 0000 0001 0000
0040 0010
0000 0010
0000 0000 0000 0000 0000 0000 0001 0000
0040 0014
0000 0005
0000 0000 0000 0000 0000 0000 0000 0101
Assembly Example
Translation to TAL code
.text
main:
loop:
lui $6, 0x0040
ori $6, $6, 0x0004
lw $7, 4($6)
mult $9, $10
beq $0, $0, loop
ori $2, $0, 10
syscall
# la $6, a2
# b loop
# done
Memory map of text section
address
Contents (hex)
Contents (binary)
0080 0000 3c06 0040
0011 1100 0000 0110 0000 0000 0100 0000 (lui)
0080 0004 34c6 0004
0011 0100 1100 0110 0000 0000 0000 0100 (ori)
0080 0008 8cc7 0004
1000 1100 1100 0111 0000 0000 0000 0100 (lw)
0080 000c
0000 0001 0010 1010 0000 0000 0001 1000 (mult)
012a 0018
0080 0010 1000 fffd
0001 0000 0000 0000 1111 1111 1111 1101 (beq)
0080 0014 3402 000a
0011 0100 0000 0010 0000 0000 0000 1010 (ori)
0080 0018 0000 000c
0000 0000 0000 0000 0000 0000 0000 1100 (sys)
Assembly
Branch offset computation.
•At execution time:
PC  NPC + {sign extended offset field,00}
•PC points to instruction after the beq when offset
is added.
•At assembly time:
Byte offset
= target addr – (address of branch + 4)
= 00800008 – (00800010+00000004)
= FFFFFFF4 (-12)
• 3 important observations:
•Offset is stored in the instruction as a word offset
•An offset may be negative
•The field dedicated to the offset is 16 bits, range is
thus limited.
Assembly
Jump target computation.
•At execution time:
PC  {most significant 4 bits of PC, target field, 00}
•At assembly time
•Take 32 bit target address
•Eliminate least significant 2 bits (since word aligned)
•Eliminate most significant 4 bits
•What remains is 26 bits, and goes in the target field
Linking and Loading
Object file
header start/size of other parts
text Machine Language
data static data – size and initial values
relocation info instructions and data with absolute addresses
symbol table addresses of external labels
Debuggin` info
Linking and Loading
Linker
•Search libraries
•Read object files
•Relocate code/data
•Resolve external references
Loader
•Create address spaces for text & data
•Copy text & data in memory
•Initialize stack and copy args
•Initialize regs (maybe)
•Initialize other things (OS)
•Jump to startup routine
•And then address of main:
Linking and Loading
•The data section starts at 0x00400000 for the MIPS RISC processor.
•If the source code has,
.data
a1:
a2:
.word 15
.word –2
then the assembler specifies initial configuration memory as
address
0x00400000
0x00400004
contents
0000 0000 0000 0000 0000 0000 0000 1111
1111 1111 1111 1111 1111 1111 1111 1110
•Like the data, the code needs to be placed starting at a specific
location to make it work
Linking and Loading
•Consider the case where the assembly language code is
split across 2 files. Each is assembled separately.
File 1:
File2:
.data
a3: .word 0
.data
a1: .word 15
a2: .word –2
.text
main:
.text
proc5:
la $t0, a1
add $t1, $t0, $s3
jal proc5
done
lw $t6, a1
sub $t2, $t0, $s4
jr $ra
Linking and Loading
What happens to…
•
•
•
•
•
•
•
a1
a3
main
proc5
lw
la
jal
Linking and Loading
Problem: there are absolute addresses in the machine
code.
Solutions:
1. Only allow a single source file
• Why not?
2. Allow linking and loading to
• Relocate pieces of data and code sections
• Finish the machine code where symbols were left
undefined
• Basically makes absolute address a relative address
Linking and Loading
•The assembler will
•Start both data and code sections at address 0, for
all files.
•Keep track of the size of every data and code section.
•Keep track of all absolute addresses within the file.
•Linking and loading will:
•Assign starting addresses for all data and code sections,
based on their sizes.
•The blocks of data and code go at non-overlapping
locations.
•Fix all absolute addresses in the code
•Place the linked code and data in memory at the
location assigned
•Start it up
MIPS Example
Code levels of abstraction (from James Larus)
“C” code
#include <stdio.h>
int main (int argc, char *argv[])
{
int I;
int sum = 0;
for (I=0; I<=100; I++) sum += I * I;
printf (“The sum 0..100=%d\n”,sum);
}
Compile this HLL into a machine’s assembly language with the
compiler.
MIPS Example
.data
str: .asciiz “The sum 0..100=%d\n”
.text
main:
loop:
subu
sw
sw
sw
sw
$sp, 32
$31, 20($sp)
$4, 32($sp)
$0, 24($sp)
$0, 28($sp)
lw
mul
lw
addu
$14,
$15,
$24,
$25,
28($sp)
$14, $14
24($sp)
$24, $15
sw
ble
la
lw
jal
move
lw
addu
jr
$8, 28($sp)
$8, 100, loop
$4, str
$5, 24($sp)
printf
$2, $0
$31, 20($sp)
$sp, 32
$31
MIPS Assembly Language
Now resolve the labels…
addiu
sw
sw
sw
sw
sw
lw
lw
multu
addiu
slti
sw
mflo
addu
bne
sw
$sp, $sp,-32
$ra, 20($sp)
$a0, 32($sp)
$a1, 36($sp)
$0, 24($sp)
$0, 28($sp)
t6, 28($sp)
$t8, 24($sp)
$t6, $t6
$t0, $t6, 1
$at, $t0, 101
$t0, 28($sp)
$t7
$t9, $t8, $t7
$at, $0, -9
$t9, 24($sp)
lui
lw
jal
addiu
lw
addiu
jr
$a0,4096
$a1, 24($sp)
1048812
$a0, $a0, 1072
$ra, 20($sp)
$sp, $sp, 32
$ra
Which then the assembler translates into binary machine code
for instructions and data.
MIPS Machine language
00100111101111011111111111100000
10101111101111110000000000010100
10101111101001000000000000100000
10101111101001010000000000100100
10101111101000000000000000011000
10101111101000000000000000011100
10001111101011100000000000011100
10001111101110000000000000011000
00000001110011100000000000011001
00100101110010000000000000000001
00101001000000010000000001100101
10101111101010000000000000011100
00000000000000000111100000010010
00000011000011111100100000100001
00010100001000001111111111110111
10101111101110010000000000011000
00111100000001000001000000000000
10001111101001010000000000011000
00001100000100000000000011101100
00100100100001000000010000110000
10001111101111110000000000010100
00100111101111010000000000100000
00000011111000000000000000001000
00000000000000000001000000100001