1
(RICHIAMI)
INTRODUZIONE ALLA
PROGRAMMAZIONE ASSEMBLY
DI PROCESSORI MIPS
‰
‰
‰
‰
COS'E' UN PROCESSORE
IL PROCESSORE MIPS
ISA RIDOTTO eMIPS
PROGRAMMAZIONE ASSEMBLY DELL’ eMIPS
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
2
COSA E' UN PROCESSORE
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
3
INSTRUCTION SET ARCHITECTURE
‰ IL PROCESSORE È UNA MACCHINA SEQUENZIALE CHE ESEGUE
DELLE ISTRUZIONI RESIDENTI IN MEMORIA ALLO SCOPO DI
MANIPOLARE DEI DATI A LORO VOLTA RESIDENTI IN MEMORIA.
‰ L’INSTRUCTION SET ARCHITECTURE (ISA) SPECIFICA
L’INSIEME DELLE CARATTERISTICHE DEL PROCESSORE VISIBILI
AL PROGRAMMATORE. ESSO DEFINISCE L’INTERFACCIA TRA
HARDWARE E SOFTWARE.
‰ L'ISA SPECIFICA LA FUNZIONALITA' DEL PROCESSORE IN
TERMINI DI:
‰ DATI GESTITI
‰ REGISTRI INTERNI DESTINATI A CONTENERE I DATI DA
MANIPOLARE
‰ ISTRUZIONI CHE PRELEVANO DALLA MEMORIA E MANIPOLANO
QUESTI DATI
‰ ISTRUZIONI DI "SALTO"
‰ MODALITA' DI FUNZIONAMENTO SPECIALI
‰ ISTRUZIONI SPECIALI
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
4
C - ASSEMBLY - CODICE MACCHINA
CODICE
AD ALTO
LIVELLO (C)
COMPILER
CODICE
ASSEMBLY
ASSEMBLER
CODICE
MACCHINA
MEMORIA
ISTRUZIONI
(MODELLO
VERILOG)
‰ UN
PROCESSORE
È
L'ESECUTORE
DI
ISTRUZIONI DEL PROPRIO INSTRUCTION SET
‰ TRAMITE LE ISTRUZIONI MACCHINA È
POSSIBILE
ESEGUIRE
UN
QUALUNQUE
ALGORITMO SPECIFICATO IN UN LINGUAGGIO
AD ALTO LIVELLO
‰ IL PROCESSORE PUÒ ESEGUIRE LE ISTRUZIONI
DEL PROPRIO IS SOLO UNA VOLTA CHE LE
STESSE SONO STATE CONVERTITE IN
FORMATO BINARIO (CODICE MACCHINA)
‰ LA
TRASFORMAZIONE
DA
UNA
RAPPRESENTAZIONE
ALL'ALTRA
VIENE
ESEGUITA DA DEI SW DI SUPPORTO, IL
COMPILATORE E L'ASSEMBLER
INSTRUCTIONS
DATA
BUS
BUS
PROCESSORE
INSTR ADDRESSES
DATA ADDRESSES
BUS
BUS
Architetture dei Sistemi Embedded 2007/08
MEMORIA
DATI
S.M. Carta
INSTRUCTION SET ARCHITECTURE
FETCH DELLE ISTRUZIONI (I)
‰ ALLO SCOPO DI ESEGUIRE UN ALGORITMO IL PROCESSORE ESEGUE
DELLE ISTRUZIONI DEL PROPRIO IS
‰ ALL'ISTANTE 0 DELL'ESECUZIONE LE ISTRUZIONI CHE CODIFICANO IL
PROGRAMMA DA ESEGUIRE RISIEDONO NELLA MEMORIA ISTRUZIONI
‰ PER POTER ESSERE ESEGUITA DAL PROCESSORE CIASCUNA ISTRUZIONE
DEVE ESSERE CARICATA IN UN REGISTRO INTERNO DEL PROCESSORE
(FETCH DELL'ISTRUZIONE)
‰ SOLITAMENTE IL REGISTRO DESTINATO A CONTENERE L'ISTRUZIONE
CORRENTE E' DENOMINATO INSTRUCTION REGISTER (IR)
‰ IL FLUSSO DI ESECUZIONE DELLE ISTRUZIONI VIENE DEFINITO DALLA
DISLOCAZIONE IN MEMORIA DELLE ISTRUZIONI STESSE E DALLA
TECNICA DI FETCH UTILIZZATA
‰ IL FLUSSO NORMALE DI ESECUZIONE (CHE NON FA USO DELLE
ISTRUZIONI DEDICATE CHE SI OCCUPANO DI MODIFICARE TALE
FLUSSO) PREVEDE LA ESECUZIONE SEQUENZIALE DELLE ISTRUZIONI
SECONDO L'ORDINE DI SALVATAGGIO IN MEMORIA
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
5
INSTRUCTION SET ARCHITECTURE
FETCH DELLE ISTRUZIONI (II)
‰ UN REGISTRO INTERNO DEL PROCESSORE CONTIENE L'INDIRIZZO
DELLA LOCAZIONE DI MEMORIA ALL'INTERNO DELLA QUALE E'
CONTENUTA LA PROSSIMA ISTRUZIONE DA ESEGUIRE. TALE REGISTRO
PRENDE IL NOME DI PROGRAM COUNTER (PC)
‰ OGNI QUALVOLTA VIENE CARICATA ED ESEGUITA UNA ISTRUZIONE
CHE NON PREVEDA LA MODIFICA DEL FLUSSO DI ESECUZIONE IL PC
VIENE INCREMENTATO IN AUTOMATICO IN MODO CHE LA PROSSIMA
ISTRUZIONE CARICATA SULL'IR E QUINDI ESEGUITA SIA LA
SUCCESSIVA A QUELLA ATTUALMENTE ESEGUITA (SEQUENZA DI
ESECUZIONE NORMALE)
‰ LA MODIFICA DEL FLUSSO DI ESECUZIONE SEQUENZIALE VIENE
GESTITA TRAMITE LE ISTRUZIONI DI SALTO.
‰ SUPPONENDO CHE LA PRIMA ISTRUZ SIA MEMORIZZATA ALLA
LOCAZIONE DI MEMORIA 0, CHE CIASCUINA ISTRUZIONE OCCUPI UNA
SOLA LOCAZIONE, E CHE NESSUNA DELLE PRIME 10 ISTRUZIONI SIA
UNA ISTRUZIONE DI SALTO, LA SEQUENZA DI ESECUZIONE SAREBBE LA
SEGUENTE: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ...
‰ SUPPONENDO CHE LA ISTRUZIONE 3 SIA UNA ISTRUZIONE DI SALTO
(JUMP 7) LA SEQUENZA DI ESECUZIONE SAREBBE: 0, 1, 2, 3, 7, 8, 9, ...
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
6
INSTRUCTION SET ARCHITECTURE
TIPOLOGIE DI ISTRUZIONI
LE PRINCIPALI TIPOLOGIE DI ISTRUZIONI SONO 3, A CUI VANNO
AGGIUNTE ISTRUZIONI DI TIPO ETEROGENEO NON CLASSIFICABILI IN
MANIERA SINTETICA, E CHE PER ORA NON VEDIAMO.
1.
ISTRUZIONI DI SPOSTAMENTO DATI:
SI OCCUPANO DI SPOSTARE I DATI DALLA MEMORIA AI REGISTRI INTERNI
DEL PROCESSORE E VICEVERSA, ESISTONO INOLTRE ISTRUZIONI CHE
SPOSTANO I DATI FRA REGISTRI INTERNI E PIU' RARAMENTE ISTRUZIONI CHE
SPOSTANO I DATI FRA LOCAZIONI DI MEMORIA
2.
ISTRUZIONI DI MANIPOLAZIONE DATI:
SI OCCUPANO DI PRELEVARE I DATI DA LOCAZIONI (DI SOLITO DAI REGISTRI
INTERNI), DI UTILIZZARLI COME OPERANDI SORGENTE PER DELLE
OPERAZIONI LOGICO/ARITMETICHE E DI SALVARE IL RISULTAO IN ALTRE
LOCAZIONI (DI SOLITO DAI REGISTRI INTERNI).
2.
ISTRUZIONI DI MODIFICA DEL FLUSSO DI ESECUZIONE (SALTO):
SI OCCUPANO DI MODIFICARE IL CONTENUTO DEL PC IN MODO DA
MODIFICARE IL FLUSSO DI ESECUZIONE DEFINITO DALL'INCREMENTO
AUTOMATICO DEL PC STESSO
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
7
8
LA FAMIGLIA DI
PROCESSORI MIPS
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
9
LA FAMIGLIA MIPS
‰ La prima versione dell’ISA MIPS è una delle prime architetture di tipo RISC (Reduced
Instruction Set Compnent) ed è stata sviluppata da John L. Hennessy. L’ISA si è quindi
evoluta in innumerevoli versioni ciascuna delle quali è stata implementata da diverse
microarchitetture. Si parla di famiglia di processori Mips.
‰ Le più evolute versioni di processori MIPS sono attualmente integrate in dispositivi
elettronici embedded di largo utilizzo.
ƒ
Consolle per l’intrattenimento (la Playstation!!)
ƒ
Stampanti Laser
ƒ
Decoder TV Satellitare
ƒ
Router
ƒ
Navigatori satellitari per automobili
ƒ
Macchine fotografiche digitali
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
10
MIPS ISA: GENERALITA’
‰ L’architettura dei processori della famiglia Mips è di tipo load/store:
non è possibile operare direttamente sui dati residenti in memoria ma
è necessario prima copiarli nei registri interni tramite istruzioni
dedicate.
‰ E’ prevista la presenza di un moltiplicare integrato per dati a 32 bit
con risultato a 64 bit.
‰ I registri interni visibili del Mips sono:
‰32 registri general purpose a 32 bit, il registro zero contiene 0 e non può
essere modificato
‰due registri a 32 bit, Hi e Lo, per memorizzare rispettivamente i 32 bit più
significativi e i 32 bit meno significativi del risultato di moltiplicazione
‰un registro Program Counter a 32 bit, che contiene l’indirizzo
dell’istruzione da eseguire
‰un registro Interrupt Address Register
‰Registri per elaborazione Floating Point
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
11
MIPS R2000 ISA : ISTRUZIONI
Il documento che specifica l'Instruction Set completo è
disponibile sul sito
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
12
INSTRUCTION SET
MIPS R2000
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
13
INSTRUCTION SET MIPS R2000
ISTRUZIONI DI ACCESSO ALLA MEMORIA (8)
‰ 5 load e 3 store.
‰ L’indirizzo di accesso (addr) è sempre la somma dell’immediato e del contenuto del
registro puntato da rs
Nome
Sintassi
Descrizione
Load word
lw rt, imm(rs)
Regs[rt]<={mem[addr],mem[addr+1],mem[addr+2],mem[addr+3]}
Load half word
lh rt, imm(rs)
Regs[rt]<={{16{mem[addr]31}},mem[addr],mem[addr+1]}
Load byte
lb rt, imm(rs)
Regs[rt]<={{24{mem[addr]31}},mem[addr]}
Load half word
unsigned
lhu rt, imm(rs)
Regs[rt]<={{16{1’b0}},mem[addr]}
Load byte unsigned
lbu rt, imm(rs)
Regs[rt]<={{24{1’b0}}mem[addr]}
Store word
sw rt, imm(rs)
Mem[addr]<=Regs[rt]
Store half word
sh rt, imm(rs)
Mem[addr]<=Regs[rt][15:0]
Store byte
sb rt, imm(rs)
Mem[addr]<=Regs[rt][7:0]
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
14
INSTRUCTION SET MIPS R2000
ISTRUZIONI LOGICO-ARITMETICHE CON
INDIRIZZAMENTO IMMEDIATO (10)
Nome
Sintassi
Descrizione
Addition Immediate (with
overflow)
addi rt, rs, imm
Regs[rt]<=Regs[rs]+imm
Addition Immediate (without
overflow)
addiu rt, rs, imm
Regs[rt]<=Regs[rs]+imm
And Immediate
andi rt, rs, imm
Regs[rt]<=Regs[rs] and imm
Or Immediate
ori rt, rs, imm
Regs[rt]<=Regs[rs] or imm
Xor Immediate
xori rt, rs, imm
Regs[rt]<=Regs[rs] xor imm
Sub Immediate(with overflow)
sub rt, rs, imm
Regs[rt]<=Regs[rs]-imm
Sub Immediatte(without overflow)
subu rt, rs, imm
Regs[rt]<=Regs[rs]-imm
Shift left logical
sll rd, rt, shamt
Regs[rd]<=Regs[rs]<<shamt
Shift right aritmetic
sra rd, rt, shamt
Regs[rd]=(Regs[rt]>>shamt)|({32{Regs[rs][31]}}<<(
32-shamt))
Shift right logical
srl rd, rt, shamt
Regs[rd]<=Regs[rs]>>shamt
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
15
INSTRUCTION SET MIPS R2000
ISTRUZIONI LOGICO-ARITMETICHE CON INDIRIZZ. REGISTER (19)
Nome
Sintassi
Descrizione
Absolute value
abs rt, rs
Regs[rt]=abs(Regs[rs])
Addition (with overflow)
add rd, rs, rt
Regs[rt]=Regs[rs]+Regs[rt]
Addition (without overflow)
addu rd, rs, rt
Regs[rt]=Regs[rs]+Regs[rt]
And
and rd, rs, rt
Regs[rt]=Regs[rs] and Regs[rt]
Multiply
mult rs, rt
Unsigned Multiply
multu rs, rt
Come mult senza tener conto del segno degli operandi
Negate (with overflow)
neg rd, rs
Regs[rd]=-Regs[rs]
Negate (without overflow)
negu rd, rs
Regs[rd]=-Regs[rs]
Nor
nor rd, rs, rt
Regs[rt]=Regs[rs] nor Regs[rt]
Not
not rt, rs
Regs[rd]=~Regs[rs]
Or
or rd, rs, rt
Regs[rt]=Regs[rs] or Regs[rt]
Shift left logical variable
sllv rd, rs, rt
Regs[rt]=Regs[rs]<<Regs[rt]
Shift right logical variable
srlv rd, rs, rt
Regs[rt]=Regs[rs]>>Regs[rt]
Shift right aritmetic variable
srav rd, rs, rt
Regs[rd]=(Regs[rt]>>Regs[rs]) | ({32{Regs[rs][31]}}<<(32-Regs[rs]))
Rotate left
rol rd, rs, rt
Regs[rt]=Regs[rs]+Regs[rt]
Rotate right
ror rd, rs, rt
Regs[rt]=Regs[rs]+Regs[rt]
Subtract(with overflow)
sub rd, rs, rt
Regs[rt]=Regs[rs]-Regs[rt]
Subtract(without overflow)
subu rd, rs, rt
Regs[rt]=Regs[rs]-Regs[rt]
Exclusive or
xor rd, rs, rt
Regs[rt]=Regs[rs] xor Regs[rt]
Architetture dei Sistemi Embedded 2007/08
Regs[hi]=(Regs[rs]*Regs[rt])[63:32]
Regs[lo]=(Regs[rs]*Regs[rt])[31:0]
S.M. Carta
INSTRUCTION SET MIPS R2000
ISTRUZIONI DI COMPARAZIONE (12)
‰ 2 con indirizzamento immediato e 10 con indirizzamento register
Nome
Sintassi
Descrizione
Set on less than
slt rd, rs, rt
If(Regs[rs]<Regs[rt]) Regs[rd]=1 else Regs[rd]=0
Set on less than unsigned
sltu rd, rs, rt
Come slt senza tenere conto del segno degli operandi
Set on less than immediate
slti rt, rs, imm
If(Regs[rs]<imm) Regs[rd]=1 else Regs[rd]=0
Set on less than immediate unsigned
sltiu rt, rs, imm
Come slti senza tenere conto del segno degli operandi
Set on equal
seq rd, rs, rt
If(Regs[rs]=Regs[rt]) Regs[rd]=1 else Regs[rd]=0
Set on greater than or equal
sge rd, rs, rt
If(Regs[rs]>=Regs[rt]) Regs[rd]=1 else Regs[rd]=0
Set on greater than or equal unsigned
sgeu rd, rs, rt
Come sge senza tenere conto del segno degli operandi
Set on greater than
sgt rd, rs, rt
If(Regs[rs]>Regs[rt]) Regs[rd]=1 else Regs[rd]=0
Set on greater than unsigned
sgtu rd, rs, rt
Come sgt senza tenere conto del segno degli operandi
Set on less than or equal
sle rd, rs, rt
If(Regs[rs]<=Regs[rt]) Regs[rd]=1 else Regs[rd]=0
Set on less than or equal unsigned
sleu rd, rs, rt
Come sle senza tenere conto del segno degli operandi
Set on not equal
sne rd, rs, rt
If(Regs[rs]!=Regs[rt]) Regs[rd]=1 else Regs[rd]=0
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
16
INSTRUCTION SET MIPS R2000
ISTRUZIONI DI SALTO CONDIZIONATO (17)
‰ LABEL indica l'istruzione alla quale saltare
Nome
Sintassi
Descrizione
Branch on equal
beq rs, rt, LABEL
Salta se Regs[rs]=Regs[rt]
Branch on greater than equal zero
bgez rs, LABEL
Salta se Regs[rs]>=0
Branch on greater than equal zero and link
bgezal rs, LABEL
Salta e Regs[31]<=PC+4 se Regs[rs]>=0
Branch on greater than zero
bgtz rs, LABEL
Salta se Regs[rs]>0
Branch on less than equal zero
blez rs, LABEL
Salta se Regs[rs]<=0
Branch on less than and link
bltzal rs, LABEL
Salta e Regs[31]<=PC+4 se Regs[rs]<0
Branch on less than zero
bltz rs, LABEL
Salta se Regs[rs]<0
Branch on not equal
bne rs, rt, LABEL
Salta se Regs[rs]!=Regs[rt]
Branch on greater than equal
bge rs, rt, LABEL
Salta se Regs[rs]>=Regs[rt]
Branch on greater than equal unsigned
bgeu rs, rt, LABEL
Come bge senza tenere conto del segno degli operandi
Branch on greater than
bgt rs, rt, LABEL
Salta se Regs[rs]>Regs[rt]
Branch on greater than unsigned
bgtu rs, rt, LABEL
Come bgt senza tenere conto del segno degli operandi
Branch on less than equal
ble rs, rt, LABEL
Salta se Regs[rs]<=Regs[rt]
Branch on less than equal unsigned
bleu rs, rt, LABEL
Come ble senza tenere conto del segno degli operandi
Branch on less than
blt rs, rt, LABEL
Salta se Regs[rs]<Regs[rt]
Branch on less than unsigned
bltu rs, rt, LABEL
Come blt senza tenere conto del segno degli operandi
Branch on not equal zero
bnez rs, rt, LABEL
Salta se Regs[rs]!=0
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
17
INSTRUCTION SET MIPS R2000
ISTRUZIONI DI SALTO INCONDIZIONATO (4)
Nome
Sintassi
Descrizione
Jump
j target
PC={{(PC+4)[31:28]},{target},{2’b00}}
Jump and link
jal target
Regs[31]<=PC+4 e PC={{(PC+4)[31:28]},{target},{2’b00}}
Jump register
jr rs
PC=Regs[rs]
Jump and link register
jalr rs, rd
Regs[rd]<=PC+4 e PC=Regs[rs]
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
18
INSTRUCTION SET MIPS R2000
ISTRUZIONI DI SPOSTAMENTO DATI FRA REGISTRI (4)
Nome
Sintassi
Descrizione
Move from hi
mfhi rd
Regs[rd]=Regs[hi]
Move from lo
mflo rd
Regs[rd]=Regs[hi]
Move to hi
mthi rs
Regs[hi]=Regs[rs]
Move to lo
mtlo rs
Regs[lo]=Regs[rs]
ISTRUZIONI DI MANIPOLAZIONI COSTANTI A 32 BIT (1)
Nome
Sintassi
Descrizione
Load upper immediate
lui rt, imm
Regs[rt]<= {imm,{16’h0 } }
ISTRUZIONI SPECIALI (2)
Nome
Sintassi
Descrizione
No operation
nop
-
Return from exeption
rfe
PC<=IAR e int_enable=1
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
19
20
INSTRUCTION SET MIPS R2000
PSEUDO-ISTRUZIONI (2)
Nome
Sintassi
Descrizione
Implementazione
move
move Rs, Rd
Regs[Rd]=Regs[Rs]
add Rd, Rs, $0
load 32 bit
immediate
li Rd, imm32
Regs[Rd] = imm32
lui Rd, imm[31:16]
ori Rd, Rd, imm[15:0]
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
21
MIPS R2000 ISA DEDICATO AGLI INTERI
‰Ci occuperemo del sottoinsieme dell’ISA del MIPS R2000
(da ora in poi semplicemente MIPS ISA) dedicato agli
interi. Trascureremo per motivi di tempo la gestione
dell’elaborazione floating point (che è comunque opzionale
nella maggior parte degli ISA per elaborazione embedded)
‰Il sottoinsieme dedicato agli interi consta di 75 istruzioni,
che possono essere classificate per funzionalità:
‰Istruzioni di lettura e scrittura dalla memoria (8)
‰Istruzioni aritmetico-logiche (40)
‰Istruzioni di scambio dati fra registri interni (4)
‰Istruzioni di modifica del flusso di esecuzione
‰Salto incondizionato (4)
‰Salto condizionato (17)
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
22
MIPS ISA: FORMATO DELLE ISTRUZIONI
ƒ
Le istruzioni sono a lunghezza fissa (32 bit), in tre possibili formati:
1. Immediate (I Type)
opcode
rs
rt
Immediate
6bit
5bit
5bit
16bit
2. Reg Type (R Type)
opcode
rs
rt
rd
shamt
function
6bit
5bit
5bit
5bit
5bit
6bit
3. Jump (J Type)
opcode
6bit
Architetture dei Sistemi Embedded 2007/08
target
26bit
S.M. Carta
23
MIPS ISA RIDOTTO: eMIPS
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
24
INSTRUCTION SET eMIPS
‰ Inizieremo la trattazione analizzando un sottoinsieme minimo delle
istruzioni, che chiameremo eMIPS
‰ Non è implementata la moltiplicazione, non vi sono quindi istruzioni
di scambio fra registri interni.
‰ L’IS semplificato contiene almeno una istruzione per ciascuna delle
categorie rimanenti:
ƒ Istruzioni di lettura e scrittura dalla memoria (2 su 8)
ƒ Istruzioni aritmetico-logiche (5 su 40)
ƒ Istruzioni di scambio di dati tra registri interni (0 su 4)
ƒ Istruzioni di modifica del flusso di esecuzione
- Salto incondizionato (0 su 4)
- Salto condizionato (1 su 17)
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
25
INSTRUCTION SET eMIPS
‰ load word (lw): carica su un registro interno un valore dalla memoria
‰ store word (sw): scrive in memoria il valore contenuto in un registro
‰ add : somma del valore di due registri
‰ subtract (sub): sottrazione tra il valore di due registri
‰ and: and logico bit a bit del contenuto di due registri
‰ or: or logico bit a bit del contenuto di due registri
‰ set on less than (slt): scrive 1 sul registro destinazione se il primo
operando è minore del secondo, zero altrimenti.
‰ branch on equal (beq): salto condizionato all'uguaglianza dei valori
contenuti nei 2 registri confrontati
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
26
INSTRUCTION SET eMIPS
NOTAZIONE CON INDICAZIONE DI REGISTRI GENERICI
DESCRIZIONE
ASSEMBLY
FUNZIONALITA’
Load word
lw Rt, imm(Rs)
REGS[Rt] = Mem(REGS[Rs]+imm)
Store word
sw Rt, imm(Rs)
Mem(REGS[Rs] + imm) = REGS[Rt]
Add
add Rd, Rs, Rt
REGS[Rd] = REGS[Rs] + REGS[Rt]
Subtract
sub Rd, Rs, Rt
REGS[Rd] = REGS[Rs] – REGS[Rt]
And
and Rd, Rs, Rt
REGS[Rd]= REGS[Rs] and REGS[Rt]
Or
or Rd, Rs, Rt
REGS[Rd] = REGS[Rs] or REGS[Rt]
Set on less than
slt Rd, Rs, Rt
if (REGS[Rs]<REGS[Rt]) REGS[Rd] = 1
Branch if equal
beq Rs, Rt, label1 if (REGS[Rs]==REGS[Rt]) PC = PC+4+imm
N.B.
ƒ REGS[Rs] = contenuto del registro Rs del register file
ƒ imm = valore che concorre a definire la locazione di memoria interessata al trasferimento
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
27
INSTRUCTION SET eMIPS
NOTAZIONE CON INDICAZIONE DI REGISTRI DI ESEMPIO
DESCRIZIONE
ASSEMBLY
FUNZIONALITA’
Load word
lw $3, 0x0100($2)
REGS[$3] = Mem(REGS[$2]+0x0100)
Store word
sw $3, 0x0100($2)
Mem(REGS[$2] + 0x0100) = REGS[$3]
Add
add $4, $2, $3
REGS[$4] = REGS[$2] + REGS[$3]
Subtract
sub $4, $2, $3
REGS[$4] = REGS[$2] – REGS[$3]
And
and $4, $2, $3
REGS[$4]= REGS[$2] and REGS[$3]
Or
or $4, $2, $3
REGS[$4 = REGS[$2] or REGS[$3]
Set on less than
slt $4, $2, $3
if (REGS[$2]<REGS[$3]) REGS[$4] = 1
Branch if equal
beq $2, $3, label1
if (REGS[$2]==REGS[$3]) PC = PC+4+imm
N.B.
ƒ $2 = REGISTRO 2
ƒ REGS[$2] = contenuto del registro $2 del register file
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
INSTRUCTION SET eMIPS: GESTIONE DELLA MEMORIA
‰ L'ISA MIPS completo gestisce dati di 6 tipi diversi: a 8, 16, 32 bit in
rappresentazione naturale o complemento a 2.
‰ Il sistema di memoria deve poter gestire tutti i tipi di dato esistenti, fornendo i dati in
uscita nella maniera appropriata, a seconda del valore assunto dai bit di controllo
associati (opType). Essendo il dato minimo a 8 bit, la locazione di memoria
elementare deve essere di 8 bit
@100 01 // Most significant byte del dato 1
@101 21 // byte 2 del dato 1
@102 AB // byte 3 del dato 1
@103 00 // Least significant byte del dato 1
@104 43 // Most significant byte del dato 2
@105 01 // Least significant byte del dato 2
@106 C1 // Dato 3
DATO 1, a 32 bit: 0121AB00
DATO 2, a 16 bit: 4301
DATO 3, a 8 bit: C1
always @(Addr) // MODELLO VERILOG DELLA MEMORIA DATI
case (opType)
(word)
DataOut = {Data[Addr+0],Data[Addr+1],Data[Addr+2],Data[Addr+3]};
(halfword) DataOut = {16’h0000,Data[Addr+0],Data[Addr+1]};
(byte)
DataOut = {24’h000000, Data[Addr] };
endcase
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
28
INSTRUCTION SET eMIPS: GESTIONE DELLA MEMORIA
‰ Per non escludere la possibilità che al processore sia associato un sistema di memoria
con memoria dati ed istruzioni non separate (memoria unica, modello di Von
Neumann) è necessario che anche la memoria istruzioni sia indirizzabile un byte alla
volta, nonostante le istruzioni siano sempre di 4 byte
‰ Ciò implica che l'aggiornamento del PC sia di 4 in 4.
@000 01 // Most significant byte dell’istr 1
@001 21
@002 AB
@003 00 // Least significant byte dell’istr 1
@004 43 // Most significant byte dell’istr 2
@005 01
@006 C1
@007 01 // Least significant byte dell’istr 2
ISTRUZIONE 1:0121AB00
ISTRUZIONE 2: 4301C101
always @(Addr) // MODELLO VERILOG DELLA MEMORIA INSTRUZIONI
DataOut = {Data[Addr+0],Data[Addr+1],Data[Addr+2],Data[Addr+3]};
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
29
30
PROGRAMMAZIONE ASSEMBLY
DEL PROCESSORE eMIPS-sc
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
31
PROGRAMMAZIONE ASSEMBLY: ISTRUZIONI DI ASSEGNAMENTO
SIMULAZIONE eMIPS_S1
Specifica C
integer A,B,C; // dati a 32 bit
C = A + B;
Specifica aggiuntiva 1:
memoria dati (t=0)
@0100 A
@0104 B
eMIPS assembly
lw $1,0x0100($0)
lw $2, 0x0104($0)
add $3,$2,$1
sw $3, 0x0200($0)
Specifica aggiuntiva 2:
memoria dati (t=fine simulaz)
@0200 C
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
32
PROGRAMMAZIONE ASSEMBLY: ESECUZIONE CONDIZIONALE (1)
L'ESECUZIONE CONDIZIONALE PUÒ ESSERE GESTITA TRAMITE L'USO
DI ISTRUZIONI DI SALTO CONDIZIONATO E DI SALTO
INCONDIZIONATO.
if (cond)
A;
else
B;
if (cond)
A;
Architetture dei Sistemi Embedded 2007/08
branch(cond==1),tagA;
B;
branch(1),end;
tagA:
A;
end:
branch(cond==1),tagA;
branch(1),end;
tagA:
A;
end:
S.M. Carta
33
PROGRAMMAZIONE ASSEMBLY: ESECUZIONE CONDIZIONALE (2)
SIMULAZIONE eMIPS_S2
Specifica C
integer A,B,C; // dati a 32 bit
if (A!=B)
C = A + B;
else
C = A - B;
Specifica aggiuntiva 1:
memoria dati (t=0)
@0100 A
@0104 B
eMIPS assembly
lw $1,0x0100($0)
lw $2, 0x0104($0)
beq $1,$2, else_tag
if_tag:
add $3,$2,$1
beq $0,$0, store
else_tag:
sub $3,$2,$1
store:
sw $3, 0x0200($0)
Specifica aggiuntiva 2:
memoria dati (t=fine simulaz)
@0200 C
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
PROGRAMMAZIONE ASSEMBLY: CICLI E VETTORI (1)
SIMULAZIONI eMIPS_S3 ed eMIPS_S4: SPECIFICA C
Specifica C
integer acc; // dati a 32 bit
integer a[16];
acc = 0;
for( i=0; i<16;i++ )
acc=acc+a[i];
Specifica aggiuntiva 1:
memoria dati (t=0)
@100 a[0]
@104 a[1]
…
@13C a[15]
@400 0x1F
@404 0x4
Specifica aggiuntiva 2:
memoria dati (t=fine simulaz)
@0200 acc
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
34
PROGRAMMAZIONE ASSEMBLY: CICLI E VETTORI (2)
L'ESECUZIONE CICLICA (LOOP) VIENE GESTITA TRAMITE L'UTILIZZO
DI UN REGISTRO DETTO INDICE CHE:
‰ VIENE INIZIALIZZATO ALL'ESTERNO DEL LOOP IN FUNZIONE DEL
NUMERO DI ITERAZIONI DA ESEGUIRE
‰ VIENE AGGIORNATO AD OGNI ITERAZIONE DEL LOOP
‰ VIENE TESTATO AD OGNI ITERAZIONE DEL LOOP, IL TEST CHE
VERIFICA LA FINE DEL CICLO NE INTERROMPE L'ESECUZIONE
L'ACCESSO AGLI ELEMENTI DI UN VETTORE CON INDICE DIPENDENTE
DALL'INDICE DEL LOOP PUO' ESSERE GESTITA TRAMITE UN
REGISTRO DETTO PUNTATORE CHE:
‰ VIENE INIZIALIZZATO ALL'ESTERNO DEL LOOP
‰ VINE UTILIZZATO AD OGNI ITERAZIONE DEL LOOP PER COMPORRE
L'INDIRIZZO DELLA LOCAZIONE CORRENTE
‰ VIENE AGGIORNATO AD OGNI ITERAZIONE DEL LOOP.
L'AGGIORNAMENTO DIPENDE DAL NUMERO DI LOCAZIONI DI
MEMORIA OCCUPATE DA CIASCUN ELEMENTO DEL VETTORE
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
35
PROGRAMMAZIONE ASSEMBLY: CICLI E VETTORI (3)
SIMULAZIONE eMIPS_S3: CODIFICA ASSEMBLY
UTILIZZO DEI REGISTRI
‰ $1 HA LA FUNZIONE DI REGISTRO ACCUMULATORE
‰ $2 HA LA FUNZIONE DI INDICE DEL LOOP
‰ $3 HA LA FUNZIONE DI PUNTATORE ALL'ELEMENTO CORRENTE DEL
VETTORE
‰ $4 MEMORIZZA LA COSTANTE USATA PER AGGIORNARE IL REGISTRO INDICE
‰ $5 MEMORIZZA LA COSTANTE USATA PER AGGIORNARE IL REGISTRO
PUNTATORE
‰ $6 MEMORIZZA LA COSTANTE USATA PER IL TEST DI FINE CICLO
‰ $7 HA LA FUNZIONE DI BUFFER TEMPORANEO
‰ LA
SEQUENZA
UTILIZZATA
E'
CRESCENTE,
DALL'ELEMENTO
1
ALL'ELEMENTO 15. L'ELEMENTO 0 E' UTILIZZATO PER INIZIALIZZARE
L'ACCUMULATORE
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
36
PROGRAMMAZIONE ASSEMBLY: CICLI E VETTORI (4)
SIMULAZIONE eMIPS_S3: CODIFICA ASSEMBLY
lw $1,0x100($0) ; inizializza il registro accumulatore $1 col dato a[0]
add $2,$0,$0 ; inizializza il reg indice $2 a 0
add $3,$0,$0 ; inizializza il reg puntatore $3 a 0
lw $4,0x400($0) ; inizializza il reg $4 utilizzato per aggiornare il registro indice
lw $5,0x404($0) ; inizializza il reg $5 utilizzato per aggiornare il reg puntatore
lw $6,0x408($0) ; inizializza il registro utilizzato per il test di fine ciclo a 15=0xF
loop:
add $2,$2,$4 ; aggiorna il registro indice sommando 1
add $3,$3,$5 ; aggiorna il registro puntatore sommando 4
lw $7, 0x100($3); carica il dato a[i] sul registro buffer $7, la seq è 1,2,..,15.
add $1,$1,$7 ; aggiorna l'accumulatore sommando il buffer
beq $2,$6,store ; fa il test del registro indice, se $2=$6 interrompe il ciclo
beq $0,$0, loop ; salta all'inizio del ciclo
store:
sw $1,0x200($0) ; scrive il risultato in memoria
;la coppia di istruzioni seguente provoca lo stop della simulazione
lw $10, 0x500($0);
sw $0, 0x0($10) ;
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
37
PROGRAMMAZIONE ASSEMBLY: CICLI E VETTORI (5)
SIMULAZIONE eMIPS_S4: CODIFICA ASSEMBLY
‰ E' POSSIBILE UTILIZZARE UN SOLO REGISTRO CHE ACCORPI LE
FUNZIONALITA' DI REGISTRO INDICE PER PER IL TEST DI FINE CICLO
E DI REGISTRO PUNTATORE
‰ IN QUESTO CASO L'INIZIALIZZAZIONE E L'AGGIORNAMENTO DEL
REGISTRO, NONCHE' IL TEST DI FINE CICLO, VANNO GESTITI IN
FUNZIONE DEL FATTO CHE LA FUNZIONALITA' DI REGISTRO
PUNTATORE RICHIEDE L'ACCESSO A DATI CHE POSSONO OCCUPARE
PIU' LOCAZIONI DI MEMORIA
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
38
PROGRAMMAZIONE ASSEMBLY: CICLI E VETTORI (6)
SIMULAZIONE eMIPS_S4: CODIFICA ASSEMBLY
UTILIZZO DEI REGISTRI
‰ $1 HA LA FUNZIONE DI REGISTRO ACCUMULATORE
‰ $2 HA LA FUNZIONE DI INDICE DEL LOOP E ANCHE DI PUNTATORE
ALL'ELEMENTO CORRENTE DEL VETTORE
‰ $3 HA LA FUNZIONE DI BUFFER TEMPORANEO
‰ $4 MEMORIZZA LA COSTANTE USATA PER AGGIORNARE IL REGISTRO
INDICE-PUNTATORE
‰ LA SEQUENZA UTILIZZATA E' STAVOLTA DECRESCENTE, DALL'ELEMENTO 15
ALL'ELEMENTO 1. L'ELEMENTO 0 E' UTILIZZATO PER INIZIALIZZARE
L'ACCUMULATORE
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
39
PROGRAMMAZIONE ASSEMBLY: CICLI E VETTORI (7)
SIMULAZIONE eMIPS_S4: CODIFICA ASSEMBLY
lw $1,0x100($0) ; inizializza l'accumulatore col dato a[0]
lw $2,0x400($0) ; inizializza il reg indice/puntatore $2
lw $4,0x404($0) ; inizializza il reg utilizzato per aggiornare il reg indice/puntatore
loop:
lw $3, 0x100($2); carica il dato su $3, la seq è 15,14,..,1.
sub $2,$2,$4 ; aggiorna il registro indice sottraendo 4
add $1,$1,$3 ; aggiorna l'accumulatore
beq $2,$0,store ; fa il test del registro indice, se $2=0 interrompe il ciclo
beq $0,$0, loop ; salta all'inizio del ciclo
store:
sw $1,0x200($0); scrive il risultato in memoria
;la coppia di istruzioni seguente provoca lo stop della simulazione
lw $10, 0x500($0);
sw $0, 0x0($10);
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
40
41
MIPS: TRADUZIONE
ASSEMBLY -> LINGUAGGIO MACCHINA
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
42
MIPS: TRADUZIONE ASSEMBLY => LINGUAGGIO MACCHINA
CODIFICA IN LINGUAGGIO MACCHINA: eMIPS_S2-ISTR #0
lw $1, 0x100($0) // inizializza l’accumulatore col dato a[0]
Istruzioni I-type: lw Rt, Imm(Rs)
ASM
BIN
BIN
HEX
HEX
opcode
Rs
Rt
Immediate
6 bit
5 bit
5 bit
16 bit
Op=6h’23 Rs=$0 Rt=$1
Imm=16h’100
100011 00000 00001 0000000100000000
1000 1100 0000 0001 0000 0001 0000 0000
8
c
0
1
0
1
0
0
8c010100
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
43
MIPS: TRADUZIONE ASSEMBLY => LINGUAGGIO MACCHINA
CODIFICA IN LINGUAGGIO MACCHINA: eMIPS_S2-ISTR #1
lw $2, 0x104($0) // inizializza l’accumulatore col dato a[0]
Istruzioni I-type: lw Rt, Imm(Rs)
ASM
BIN
BIN
HEX
HEX
opcode
Rs
Rt
Immediate
6 bit
5 bit
5 bit
16 bit
Op=6h’23 Rs=$0 Rt=$2
Imm=16h’104
100011 00000 00010 0000000100000100
1000 1100 0000 0010 0000 0001 0000 0100
8
c
0
2
0
1
0
4
8c020104
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
44
FRAMEWORK PER L'ESECUZIONE DI
APPLICAZIONI ASSEMBLY SUL
MODELLO VERILOG DI UN SISTEMA
DI ELABORAZIONE BASATO SUL
PROCESSORE eMIPS-sc
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
45
MODELLO VERILOG DEL PROCESSORE
MODELLO VERILOG DEL SISTEMA COMPLETO
La gerarchia del modello verilog del sistema è la seguente:
testbench.v (istanza testbench)
instructions_ROM.v (istanza InstrROM)
data_RAM.v (istanza DataRAM)
eMIPS_sc.v (istanza MIPS)
pc_reg.v (istanza PC)
pc_adder.v (istanza NPC)
....
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
46
FRAMEWORK DI SVILUPPO (I)
MIPS
ASSEMBLER
file
instructions.hex
MEMORIA
ISTRUZIONI
(MODELLO
VERILOG)
DATI
INIZIALI
CON CONVERSIONE IN UN
FORMATO LEGGIBILE DAL
SIMULATORE VERILOG
(READMEMH)
INSTRUCTIONS
BUS
INSTR ADDRESSES
DATA
MIPS
(MODELLO
VERILOG)
BUS
DATA ADDRESSES
BUS
BUS
CONVERSIONE IN UN
FORMATO LEGGIBILE
DAL SIMULATORE
VERILOG (READMEMH)
Architetture dei Sistemi Embedded 2007/08
CODICE
ASSEMBLY
MEMORIA
DATI
(MODELLO
VERILOG)
SIMULATORE
VERILOG
(MODELSIM)
file
data_RAM.hex
S.M. Carta
47
FRAMEWORK DI SVILUPPO (II)
STRUTTURA DI FILE E DIRECTORY
‰ eMIPS-sc_S3
ƒ
ƒ
ƒ
‰
S1.mpf
compila.bat
eMIPS_S3.asm
HEX
ƒ instructions.hex
ƒ data_ram.hex
‰ ASM
ƒ
file eseguibili dell'assembler.....
‰ VERILOG
ƒ testbench_eMIPS_S3.v
‰ Memories
‰ eMIPS-sc
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
48
ESECUZIONE DI APPLICAZIONI SU
SISTEMI EMBEDDED MIPS-based
SPECIFICA MISTA C-ASSEMBLY, UTILIZZO
DELLA MEMORIA A BASSO LIVELLO,
CONVENZIONI DI CHIAMATA A
SUBROUTINE
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
49
INTERFACCIA HW/SW
‰ L’utilizzo di programmi scritti in linguaggi ad alto livello (c/c++) sul
processore di un sistema embedded richiede la specifica di una serie di
informazioni
supplementari
(dimensione
della
memoria,
partizionamento e mappa della memoria, routine di boot, routine di
interrupt, ecc.) che non possono essere definite a livello di software c
stesso, ma vanno definite a livello assembly-sistema operativo.
‰ Si rende necessaria l’integrazione di specifiche scritte a livelli diversi:
c e assembly
‰ Si rende inoltre necessario la conoscenza della strategia usata dal
compilatore c utilizzato (nel nostro caso il gcc 2.95.3) per la gestione a
basso livello della memoria
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
50
INTERFACCIA HW/SW
‰ Per fissare i primi concetti legati al funzionamento del compilatore e
all'utilizzo dei tool di compilazione semplificati (compilatore + assembler)
sviluppati per questo corso, utilizzeremo un semplice sistema processorememoria senza periferiche
‰ La microarchitettura MIPS che utilizzeremo è la MIPS-mc. L'architettura di
memoria di Von Neumann: vi è una sola memoria condivisa da dati ed
istruzioni
WriteEnable Signal
global
clk
MIPS-mc
Instructions / Data
Buses
reset
System
Architetture dei Sistemi Embedded 2007/08
INSTRUCTIONS
/ DATA
MEMORY
Addresses
Bus
S.M. Carta
51
GESTIONE DELLA MEMORIA PER I
SISTEMI MONOPROGRAMMATI
IN MODALITA’ REALE
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
52
INTERFACCIA HW/SW
CONVENZIONI PER LA GESTIONE DELLA MEMORIA
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
53
INTERFACCIA HW/SW
UTILIZZO DELLA MEMORIA (VERSIONE SEMPLIFICATA) (I)
‰ Il compilatore utilizza la memoria dividendola in due parti: lo Stack e lo
Heap.
‰ Lo stack è la porzione di memoria gestita automaticamente dal processore,
inizia a partire dalle locazioni con indirizzo più alto e ha una dimensione
variabile in funzione dello spazio di cui ha bisogno il programma.
‰ Lo heap è invece la zona di memoria gestita dinamicamente, con le funzioni
malloc e calloc.
‰ Lo Heap inizia dalle locazioni di memoria più basse e si riempie verso
locazioni di indirizzo più elevato.
‰ Non avendo a disposizione le funzioni di libreria malloc e calloc allocheremo
i dati in memoria in maniera esplicita tramite i puntatori.
‰ Utilizzeremo inoltre una zona di memoria per il salvataggio dei dati relativi
alle routine di interrupt o ad altre routine speciali.
‰ Chiameremo la memoria utilizzata in questo modo MEMORIA ALLOCATA
MANUALMENTE (MAM)
‰ In un sistema di Von Neumann, la parte della memoria di indirizzi più bassi,
da zero in poi, viene utilizzata per le istruzioni.
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
54
INTERFACCIA HW/SW
UTILIZZO DELLA MEMORIA (VERSIONE SEMPLIFICATA) (II)
‰ A partire dagli indirizzi di memoria
più alti sta la funzione main, il
compilatore alloca ricorsivamente lo
spazio per le procedure allocando e
disallocando zone di memoria.
‰ Ogni procedura ha a disposizione
una zona di memoria privata definita
frame di attivazione. Lo spazio dei
frame di attivazione è lo stack
‰ La memoria di tipo dinamico viene
allocata a partire dagli indirizzi bassi
e si espande verso quelli alti, a
partire da un certo indirizzo in poi.
‰ La MAM si può allocare o fra lo
heap (sotto lo heap) e la memoria
istruzioni (sopra la mem istruzioni)
oppure sopra lo stack
‰ Per sistemi a memoria condivisa fra
dati ed istruzioni la parte più bassa
della memoria è dedicata alle
istruzioni.
Architetture dei Sistemi Embedded 2007/08
TOP OF MEMORY
main FP
M.A.M.
MAIN DATA
FUNC 1 DATA
MEMORIA
DATI
GESTITA
DAL
COMPILATORE
STACK:
MEMORIA AUTOMATICA
ALLOCATA DAL
COMPILATORE
FUNC 2 DATA
HEAP
HEAP:
MEMORIA DINAMICA
ALLOCATA DAL
COMPILATORE TRAMITE
MALLOC O CALLOC
M.A.M.
SPAZIO
ISTRUZIONI
TEXT
locazione 0
S.M. Carta
INTERFACCIA HW/SW
MECCANISMO DI CHIAMATA DI PROCEDURA
‰ Un opportuno sottoinsieme delle istruzioni dell'IS MIPS viene utilizzato
per supportare la chiamata di una procedura (funzione), ed una volta
terminata la sua esecuzione, il ritorno alla istruzione successiva alla
chiamata
‰ Ogni volta che deve essere convertita in assembly una chiamata a
funzione viene utilizzata una istruzione che forza il salto all'indirizzo
della prima istruzione della procedura, e simultaneamente salva quello
dell'istruzione successiva nel registro $31. Tale istruzione è
jal label_procedura
‰ Ogni procedura deve terminare con una istruzione che forza il valore del
PC all'indirizzo della istruzione successiva a quella di chiamata, cioè
all'indirizzo salvato in $31. Tale istruzione è
jr $31
‰ Per gestire la possibilità che una funzione ne chiami a sua volta un'altra,
sovrascrivendo l'indirizzo di ritorno in $31, è necessario che questo venga
salvato in memoria
‰ E' necessaria una convenzione che definisca come salvare in memoria
l'indirizzo di ritorno nonchè i parametri passati alla procedura, i dati
locali, ecc.
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
55
56
INTERFACCIA HW-SW
GESTIONE DELLO STACK (I)
‰ Quando viene eseguita una funzione
viene riservata ad essa una porzione
dello stack detta frame. La
dimensione del frame dipende dal
numero di dati relativi alla funzione
che è necessario scrivere in memoria FRAME$30POINTER
e può essere anche nulla se non ci
sono dati da memorizzare.
‰ Le informazioni da memorizzare per
ogni frame sono:
ƒ parametri della funzione invocata oltre il
quarto (i primi quattro parametri sono
salvati nei registri da $4 a $7)
ƒ indirizzo di ritorno
ƒ dati locali della funzione
ƒ registri temporanei che verranno
sovrascritti durante l'esecuzione della
funzione
Architetture dei Sistemi Embedded 2007/08
$29
STACK POINTER
PARAMETRO N
PARAMETRO 5
PARAMETRI
DELLA
FUNZIONE
(oltre il quarto)
FP DELLA FUNZ CHIAMANTE
INDIRIZZO DI RITORNO
LOCAL DATA 1
DATI LOCALI
DELLA FUNZIONE
LOCAL DATA N
VALORE SALVATO DI $8
VALORE SALVATO DI $n
S.M. Carta
VALORE SALVATO
DEI REGISTRI
UTILIZZATI
DURANTE
LA FUNZIONE
57
INTERFACCIA HW-SW
CONVENZIONE DI CHIAMATA DI PROCEDURA PER MIPS
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
58
INTERFACCIA HW-SW
GESTIONE DELLO STACK (II) ESEMPIO
void _main( void ) {
int a[2];
int i;
int *pointer;
pointer = (int*) 0x1000;
for( i=0; i<2; i++)
a[i] = i;
*pointer = a[0]+a[1];
}
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
59
INTERFACCIA HW-SW
GESTIONE DELLO STACK (III) ESEMPIO
alloca la memoria per il frame di attivazione
del main. La dim minima è di 16 locazioni.
main:
;# vars= 16, regs= 0/0, args= 0, extra= 0
subu
$sp,$sp,16
li
$3,1
addu
$2,$sp,4
$L6:
sw
addu
addu
bgez
lw
lw
#nop
addu
sw
addu
j
.end
$3,0($2)
$2,$2,-4
$3,$3,-1
$3,$L6
$2,0($sp)
$3,4($sp)
$2,$2,$3
$2,4096
$sp,$sp,16
$31
_main
..
Architetture dei Sistemi Embedded 2007/08
inizializza i registri che utilizzerà come
indici
esegue il loop, usa $2 come puntatore alla
locazione dell'elemento del vettore utilizzato
ed $3 come indice per il conteggio. Calcola il
valore degli elementi del vettore e li salva
nello stack
carica gli elementi del vettore dallo stack,
calcola la somma e la salva nella MAM
dealloca la memoria (frame di
attivazione del main) e ripristina il PC
S.M. Carta
60
INTERFACCIA HW-SW
GESTIONE DELLO STACK (IV)
‰ Il frame viene gestito attraverso due registri che sono utilizzati come puntatori: lo
Stack Pointer ($sp), che punta all’indirizzo della locazione più bassa del frame, e il
Frame Pointer ($fp), che punta alla locazione più alta. Mentre il primo è
indispensabile il secondo può in certi casi non essere utilizzato a seconda del
compilatore, del livello di ottimizzazione utilizzato e del programma in esecuzione.
‰ Lo stack pointer serve da riferimento per accedere alle locazioni del frame: per
esempio una scrittura su una locazione del frame verrà specificata con:
sw $31,20($sp)
‰ Le informazioni sul numero di dati da salvare in memoria sono forniti dal
compilatore come commenti nel programma assembly in uscita.
ƒ #vars indica il numero di locazioni utilizzate per memorizzare le variabili locali.
Se non sono dichiarati arrays questo numero è nullo.
ƒ #regs indica il numero di registri che devono essere salvati in memoria. In genere
non ce ne sono se non viene invocata una funzione.
ƒ #args indica il numero di locazioni destinate ai parametri di una funzione
invocata. Se non viene invocata nessuna funzione questo numero è zero ma se
viene invocata una funzione questo numero è sempre maggiore o uguale a 16,
anche se la funzione invocata non ha parametri.
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
61
INTERFACCIA HW-SW
GESTIONE DELLO STACK (V)
‰ All’inizio dell’esecuzione del programma lo Stack Pointer punta all’indirizzo
successivo a quello più alto in memoria, perché lo stack deve occupare la
memoria a partire dagli indirizzi più alti.
‰ Le prime istruzioni prodotte dal compilatore riguardano la gestione
automatica di memoria e registri. Ogni funzione, se ha bisogno di dati da
memorizzare, inizia con l’istruzione che fa scendere lo Stack Pointer in modo
da allocare lo spazio sufficiente. Seguono eventualmente i salvataggi dei
registri che saranno sovrascritti.
‰ La chiamata a funzione inizia sempre con un istruzione jal che porta il
processore ad eseguire la prima istruzione della funzione chiamata. A questo
punto viene creato un altro frame e così via. Alla fine di ogni funzione
l’eventuale valore restituito viene scritto sul registro $2 o $3, vengono
ripristinati i registri sovrascritti con i valori salvati in memoria e viene deallocato il frame riportando lo stack pointer alla posizione che aveva prima
della chiamata a funzione.
‰ Con l’istruzione
Jr $ra
si torna alla funzione chiamante.
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
62
INTERFACCIA HW-SW
SPECIFICA C E BOOT FILE
‰ Anche il main viene gestito come una funzione qualunque. Ma come viene
effettuata la chiamata al main?
‰ Nel caso di Sistema Operativo, vi saranno un assembler ed un linker che si
occupano di gestire la cosa in maniera trasparente per il programmatore
‰ Nel nostro caso vogliamo che tutto sia gestito in maniera esplicita, non vi è
un SO e neppure un vero linker.
‰ La chiamata del main viene eseguita tramite una specifica assembly separata
codificata in un file detto file di boot
‰ Tale file verrà unito alla traduzione assembly della specifica c dando vita ad
una specifica assembly completa, su singolo file, che può essere tradotta in
linguaggio macchina (cioè nel file di codifica delle locazioni di memoria
dedicate alle istruzioni)
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
63
INTERFACCIA HW-SW
FILE DI BOOT
‰ Il file di boot che utilizzeremo inizialmente si occupa esclusivamente delle cose essenziali,
vedremo in seguito delle specifiche più complete
‰ La prima istruzione salta sempre alla routine di inizializzazione del sistema, che in
questo caso consiste solo nell'inizializzazione dello stack pointer
‰ Una volta inizializzato il sistema viene eseguita la chiamata del main
‰ Quando si vuole che lo stack allocato automaticamente dal compilatore si estenda a partire
dalle locazioni di indirizzo massimo della memoria, il valore di inizializzazione dello
stack pointer coincide con la dimensione della memoria
J RESET_HANDLER
RESET_HANDLER: ; routine di inizializzazione del sistema
li $29,0x3000; ; inizializzazione dello stack pointer
; fine della routine di inizializzazione
jal _main ; avvia l'esecuzione del programma principale
; La simulazione termina con il blocco del PC
stop:
j stop
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
64
ESECUZIONE DI APPLICAZIONI SU
SISTEMI EMBEDDED MIPS-based:
FRAMEWORK UTILIZZATO PER
COMPILAZIONE E SIMULAZIONE
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
65
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based
FRAMEWORK DI SVILUPPO (I)
c_code.c
mips_gcc.exe -o c_code.asm -O2 -fno-delayed-branch -S c_code.c c compiler
c_code.asm
boot.asm
link instructions.asm c_code.asm boot.asm
merge
instructions.asm
mips_asm instructions.asm instructions.hex
instructions.hex
Architetture dei Sistemi Embedded 2007/08
assembler
‰ Sono necessari 2 file sorgenti
(c_code.c e boot.asm), vengono
creati
2
file
intermedi
(c_code.asm e instructions.asm)
per ottenere un file di codifica
delle istruzioni (instructions.hex).
‰ Vengono utilizzati un compilatore
c (gcc 2.95.3), un assembler (ad
hoc) ed una piccola utility che fa
il merge
‰ L’utility merge si limita ad
unire i file assembly mettendo le
istruzioni di ciascun file in
sequenza in un unica file
S.M. Carta
66
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based
FRAMEWORK DI SVILUPPO (II)
‰ Utilizzando la seguente struttura di file e cartelle
‰ La cartella principale contiene le 2 sottocartelle HEX e VERILOG e il file del
progetto con allegata la sottocartella work
‰ La cartella HEX contiene i file sorgente (mips_S1.c e mips_S1_boot.asm), il file
batch che esegue tutti i task (compila.bat), il file che codifica l'inizializzazione della
la memoria istruzioni e le sottocartelle GCC e ASM
‰I file eseguibili dell'assembler sono nella sottocartella HEX\ASM
‰I file eseguibili del compilatore sono nella sottocartella HEX\GCC
‰ La cartella VERILOG contiene il modello verilog del sistema
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
67
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based
FRAMEWORK DI SVILUPPO (III): file compila.bat
echi off
set NOME_APPLICAZIONE=MIPS_s1
cd HEX
copy %NOME_APPLICAZIONE%.c .\GCC\c_code.c
copy %NOME_APPLICAZIONE%_boot.asm .\ASM\boot.asm
cd GCC
mips_gcc.exe -o c_code.asm -O2 -fno-delayed-branch -S c_code.c
pause
copy c_code.asm ..\ASM\
cd ..\ASM
copy /B boot.asm + c_code.asm instructions.asm
copy instructions.asm ..\
@bash -rcfile mipsprofile mipsAsm.sh %1 %2 instructions.asm instructions.hex
pause
copy instructions.hex ..\
cd ..\
type instructions.hex
pause
del .\GCC\c_code.c
del .\GCC\c_code.asm
....
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
68
SIMULAZIONE 1:
ASSEGNAMENTO DI
VALORI AD UN VETTORE
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
69
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based
La memoria utilizzata (unica per dati ed istruzioni) è di 0x3000=12888 locazioni. Lo
spazio riservato alle istruzioni è di 0x1000=4096 locazioni
locazione 0x2FFC
void _main( void ) {
int a[2];
int i;
int *pointer;
pointer = (int*) 0x1000;
STACK
WriteEnable Signal
global
clk
MIPS-mc
Instructions / Data
Buses
reset
System
for( i=0; i<2; i++)
a[i] = i;
*pointer = a[0]+a[1];
}
Architetture dei Sistemi Embedded 2007/08
INSTRUCTIONS
/ DATA
MEMORY
Addresses
Bus
MAM
locazione 0x1000
ISTRUZIONI
locazione 0x0000
S.M. Carta
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based
J RESET_HANDLER
RESET_HANDLER: ; routine di inizializzazione
addi $29,$0,0x3000; ; inizializza lo stack pointer
jal _main ; avvia l'esecuzione del main
; La simulazione termina con il blocco del PC
stop:
j stop
_main:
;# vars= 16, regs= 0/0, args= 0, extra= 0
subu
$sp,$sp,16
li
$3,1
addu
$2,$sp,4
$L6:
sw
addu
addu
bgez
lw
lw
#nop
addu
sw
addu
j
.end
$3,0($2)
$2,$2,-4
$3,$3,-1
$3,$L6
$2,0($sp)
$3,4($sp)
$2,$2,$3
$2,4096
$sp,$sp,16
$31
_main
..
Architetture dei Sistemi Embedded 2007/08
inizializzazione e salto al main
alloca la memoria per il frame di attivazione
del main. La dim minima è di 16 locazioni.
inizializza i registri che utilizzerà come
indici
esegue il loop, usa $2 come puntatore alla
locazione dell'elemento del vettore utilizzato
ed $3 come indice per il conteggio. Calcola il
valore degli elementi del vettore e li salva
nello stack
carica gli elementi del vettore dallo stack,
calcola la somma e la salva nella MAM
dealloca la memoria (frame di
attivazione del main) e ripristina il PC
S.M. Carta
70
71
SIMULAZIONE 2:
CHIAMATA A FUNZIONE
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
72
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based
‰ La memoria (unica per dati ed istruzioni) utilizzata è di 0x3000=12888 locazioni. Lo
spazio riservato alle istruzioni è di 0x1000=4096 locazioni
#define dim 4
void _main( void ) {
int a[dim];
int i, *max;
for( i=0; i<dim; i++)
a[i] = i;
max = (int*) 0x1000;
*max = max_func(a,dim);
int max_func(int* vector, int size)
{
int max,i;
max = 0;
for( i=0; i<size; i++)
if (vector[i] > max)
max = vector[i];
return (max);
}
}
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
73
SIMULAZIONE 3:
MEMORIA AUTOMATICA
E
MEMORIA ALLOCATA
MANUALMENTE
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
74
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based
‰ La memoria (unica per dati ed istruzioni) utilizzata è di 0x3000=12288 locazioni. Lo
spazio riservato alle istruzioni è di 0x1000=4096 locazioni
#define size 4
void _main( void ) {
int *dinamic_v;
int automatic_v[size];
int i;
for( i=0; i<size; i++) automatic_v[i] = 10+i;
dinamic_v = (int*) 0x1000;
for( i=0; i<size; i++) dinamic_v[i] = automatic_v[i];
}
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
75
ESECUZIONE DI APPLICAZIONI SU
SISTEMI EMBEDDED MIPS-based:
DEBUG DELLE APPLICAZIONI
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based76
DEBUG DI SOFTWARE EMBEDDED
‰ Il debug di software per sistemi embedded presenta delle difficoltà aggiuntive
rispetto al debug di sw per piattaforma PC.
‰ E’ spesso impossibile definire le condizioni al contorno del SW in maniera
puramente SW (gestione delle condizioni di interrupt, della mappa della memoria
che è legata alla tipologia del sistema, ecc.). E’ indispensabile un sistema di
sviluppo di tipo HW-SW che consenta al SW embedded di interagire in tempo
reale con l’HW di contorno al processore.
‰ Nel caso di sistemi embedded di tipo SoB (System on Board) la fase finale dello
sviluppo SW è basate su sistemi di In-Circuit Emulation (ICE). Nel caso di
sistemi embedded di tipo SoC (System on Chip) si usa l’evoluzione dei sistemi
ICE. Si parla di sistemi embedded ICE
‰ I sistemi ICE sono basati su un dispositivo hardware (emulatore) che implementa
la funzionalità del processore (e può quindi venire inserito nel sistema) ma in
aggiunta manda in output tutta una serie di informazioni sul suo funzionamento
interno (valore dei registri, valori sui bus e sulle porte di I/O, ecc.). L'emulatore è
collegato ad una stazione di debug (un PC o una workstation) che può
memorizzare tutte le informazioni utili per il debug
‰ Il programmatore può monitorare le informazioni relative all'esecuzione, in modo
da rilevare e correggere eventuali (!) malfunzionamenti
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based77
DEBUG DI SOFTWARE EMBEDDED
‰ Nel nostro caso, abbiamo a disposizione un simulatore verilog che emula il
funzionamento del processore e di tutto il sistema (quindi un emulatore
completo.
‰ Utilizzeremo una tecnica che sfrutta l’inserimento di routine C dedicate che
cooperano con processi verilog ad-hoc situati nel testbench. Anche i sistemi ICE
funzionano con tecniche di questo tipo
‰ Utilizzeremo degli strumenti (breakpoints) inseribili a livello di codice c che
consentono di stoppare la simulazione e di visualizzare :
ƒ Il valore assunto da segnali, bus, porte di moduli, registri, ecc. (controllo a
livello HW)
ƒ Il contenuto dei registri interni del processore, delle locazioni mappate in
memoria, dei segnali di interrupt, e dei segnali di I/O (controllo a livello
FW)
ƒ Il valore assunto dalle variabili, dalle locazioni mappate in memoria, dai
segnali di interrupt, e dai segnali di I/O (controllo a livello SW)
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based78
DEBUG DI SOFTWARE EMBEDDED: BREAKPONTS
‰ L'inserimento di un breakpoint consente di stoppare la simulazione
‰ Questa funzionalità è stata implementata tramite una funzione c che accoppiata ad un
processo verilog nel testbench che stoppa la simulazione eseguendo una istruzione
$stop.
‰ La funzione c (denominata breakpoint()) scrive il valore 0x1 sulla locazione 0x7FFF. La
scrittura non ha alcun esito poichè non vi è alcuna locazione di memoria a
quell'indirizzo (E' vero per il nostro sistema. Per altri sistemi si possono usare altre
locazioni o altri tipi di tecniche)
‰ Il processo dedicato esegue la funzione stop ogni volta che si verifica questo tentativo di
scrittura
C LEVEL - descrizione della routine
void breakpoint(void) {
int *p_out;
p_out = (int*) 0x7FFF ;
*p_out = 0x1 ; }
C LEVEL - FRAMMENTO DI CODICE
...
breakpoint();
...
VERILOG LEVEL - PROCESSO DEDICATO PER IL BREAKPOINT
always @(posedge clk)
if ( (addr_bus == (32'h7FFF)) && (MemWrite == 1))
$stop;
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based79
DEBUG DI SOFTWARE EMBEDDED: WATCH FIRMWARE
‰ I sistemi di sviluppo dei compilatori mettono a disposizione la possibilità di visualizzare il
contenuto di registri interni, locazioni della memoria, ecc.
‰ Questa funzionalità è stata implementata tramite una funzione c che accoppiata ad un processo
verilog nel testbench che esegue una serie di display e stoppa la simulazione eseguendo una
istruzione $stop.
‰ La funzione c (denominata watch_fw()) scrive il valore 0x2 sulla locazione 0x7FFF. La scrittura
non ha alcun esito poichè non vi è alcuna locazione di memoria a quell'indirizzo (..)
‰ Il processo dedicato esegue la funzione stop e visualizza le locazioni ed i registri di interesse (da
definire di volta in volta) ogni volta che si verifica questo tentativo di scrittura
C LEVEL - descrizione della routine
void watch_fw(void) {
int *p_out;
p_out = (int*) 0x7FFF ;
*p_out = 0x2 ; }
C LEVEL - FRAMMENTO DI CODICE
...
watch_fw();
...
VERILOG LEVEL - PROCESSO DEDICATO PER IL BREAKPOINT
always @(posedge clk)
if ( (addr_bus == (32'h7FFF)) && (MemWrite == 1)) begin
$display(" $1 = 0x%x
=%d",MIPS.REGFILE.data[1], MIPS.REGFILE.data[1]);
$display(" $2 = 0x%x
=%d",MIPS.REGFILE.data[2], MIPS.REGFILE.data[2]);
$stop;
end
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based80
DEBUG DI SOFTWARE EMBEDDED: WATCH SOFTWARE
‰ I sistemi di sviluppo dei compilatori mettono a disposizione la possibilità di visualizzare il assunto
dalle variabili nel corso dell'esecuzione.
‰ Questa funzionalità è stata implementata tramite una funzione c che accoppiata ad un processo
verilog nel testbench che esegue un display e stoppa la simulazione eseguendo una istruzione
$stop.
‰ La funzione c (denominata watch_sw()) scrive il valore della variabile sulla locazione 0x7FF0 codice della variabile. La scrittura non ha alcun esito poichè non vi è alcuna locazione di memoria
a quell'indirizzo (..)
‰ Il processo dedicato esegue la funzione stop e visualizza il valore della variabile di interesse (da
definire di volta in volta) ogni volta che si verifica questo tentativo di scrittura
C LEVEL - descrizione della routine
void watch_sw(int var, int var_code) {
int *p_out;
p_out = (int*) (0x7FF0 - var_code);
*p_out = var;
}
C LEVEL - FRAMMENTO DI CODICE
(p.e. variabile con codice 3)
...
watch_sw(pippo,3);
...
watch_sw(pluto,2);
VERILOG LEVEL - PROCESSO DEDICATO PER LA VISUALIZZAZIONE DELLA VAR CON CODICE 3
always @(posedge clk)
if ( (addr_bus == (32'h7FF0 - 3 )) && (MemWrite == 1)) begin
$display(" var #3 = 0x%x
=%d", proc_dout_bus, proc_dout_bus);
$stop;
end
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based81
DEBUG DI SOFTWARE EMBEDDED
‰ Quelli illustrati sono solo 3 possibili esempi di tecniche utilizzabili per il debug in un
sistema di emulazione come il nostro
‰ E' possibile mischiare le modalità di visualizzazione, di stop della simulazione, il
salvataggio delle grandezze temporanee della simulazione di interesse su file, associare
alle grandezze il tempo di simulazione o altre grandezze stesse ecc.
‰ Disponendo di un modello del processore a basso livello ed avendo la possibilità di
visualizzare qualunque segnale, siamo simo infatti in grado di monitorare qualunque
grandezza in qualunque condizione o insieme di condizioni ci interessi.
‰ Utilizzando sistemi ICE reali le possibilità sono più limitate. In questi casi comunque si
tratta di debuggare solo l'applicazione e al limite le periferiche, mai il processore stesso.
‰ Il sistema da noi adottato ha permesso il debug anzitutto del processore
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
82
SIMULAZIONE 4:
CALCOLO DEL MASSIMO CON
INSERIMENTO DI
FUNZIONE DI DEBUG PER IL
MONITORAGGIO DEL MASSIMO
TEMPORANEO
Architetture dei Sistemi Embedded 2007/08
S.M. Carta
83
ESECUZIONE DI APPLICAZIONI SU SISTEMI EMBEDDED MIPS-based
‰ La memoria (unica per dati ed istruzioni) utilizzata è di 0x3000=12888 locazioni. Lo
spazio riservato alle istruzioni è di 0x1000=4096 locazioni
#define size 16
void _main( void ) {
int a[size];
int i, *max;
dim = 4;
for( i=0; i<dim; i++)
a[i] = (i-5)*(i-5);
max = (int*) 0x1000;
*max = max_func(a,dim);
}
Architetture dei Sistemi Embedded 2007/08
void watch_sw(int var, int var_code) {
int *p_out;
p_out = (int*) (0x7FF0 - var_code);
*p_out = var;
}
int max_func(int* vector, int dim) {
int max,i;
max = 0;
for( i=0; i<dim; i++) {
if (vector[i] > max) {
max = vector[i];
watch_sw(max, 1)}
}
return (max);
}
S.M. Carta