Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Tutti i registri che non sono utilizzati nel ruolo per essi definito dallAPCS
possono essere usati come registri generali
"#
$#
!
AREA |C$$code|, CODE, READONLY
|x$codeseg| DATA
add_64
STMDB sp!,{v1,lr}
LDR
v1,[a2,#0]
MOV
a4,v1,LSR #31
LDR
ip,[a3,#0]
MOV
lr,ip,LSR #31
ADD
ip,v1,ip
STR
ip,[a1,#0]
MOV
ip,ip,LSR #31
LDR
a2,[a2,#4]
LDR
a3,[a3,#4]
ADD
a2,a2,a3
TST
a4,lr
TEQEQ a4,ip
MOVNE a3,#1
MOVEQ a3,#0
ADD
a2,a2,a3
STR
a2,[a1,#4]!
LDMIA sp!,{v1,pc}
AREA |C$$data|,DATA
|x$dataseg|
EXPORT add_64
END
%#
immediato verificare
che il codice ottenuto
non risulta essere
efficiente
&#
!
Analizzando il codice si osserva che
la prima ADD produce la low order
word mentre la seconda la high
order word. Il codice desiderato
pu essere ottenuto semplicemente
sostituendo la prima ADD con
ADDS (ADD e SET flag) e la
seconda con ADC (ADD with
Carry)
##
add_64
LDR
LDR
ADD
ADDS
STR
LDR
LDR
ADD
ADDS
STR
MOV
a4,[a2,#0]
ip,[a3,#0]
a4,a4,ip
a4,a4,ip
a4,[a1,#0]
a2,[a2,#4]
a3,[a3,#4]
a2,a2,a3
a2,a2,a3
a2,[a1,#4]!
pc,lr
'((
'
)
add_64
STMDB sp!,{v1,lr}
LDR
v1,[a2,#0]
MOV
a4,v1,LSR #31
LDR
ip,[a3,#0]
MOV
lr,ip,LSR #31
ADD
ip,v1,ip
STR
ip,[a1,#0]
MOV
ip,ip,LSR #31
LDR
a2,[a2,#4]
LDR
a3,[a3,#4]
ADD
a2,a2,a3
TST
a4,lr
TEQEQ a4,ip
MOVNE a3,#1
MOVEQ a3,#0
ADD
a2,a2,a3
STR
a2,[a1,#4]!
LDMIA sp!,{v1,pc}
*
Tornando alla prima
versione dellassembly
possiamo osservare che
essendo utilizzati
localmente i registri v1 ed
lr sono preservati sullo
stack
Il ritorno dalla funzione
ottenibile mediante
LDMIA sp!,{v1,pc}
'
"$
lr
+
sp
sl
fp
sb
'
$$
stack pointer
stack limit , utilizzato se il controllo dei limiti
dello stack esplicito (cio realizzato dal codice
in occorrenza di un push sullo stack). Se il
controllo implicito (effettuato dallhardware) il
registro pu essere utilizzato come v7.
frame pointer. Contiene o zero o un puntatore
allultimo frame generato sullo stack.
static base. Nel caso di codice rientrante consente
laccesso ad un array di puntatori a dati statici.
Nel caso di codice non rientrante pu essere
usato come v6.
"%
Generalmente le strutture sono passate
attraverso registri o eventualmente (se le
dimensioni o il numero lo esigessero)
attraverso lo stack.
Il registro a1 punta allarea di memoria utilizzata
per la memorizzazione dei risultati (per funzioni
che ritornano strutture)
come se struct s f(int x) fosse compilata come
void f(struct s *result, int x)
$%
Si consideri il seguente codice
(ARM_home\candasm\two_ch.c)
typedef struct two_ch_struct
{ char ch1;
char ch2;
} two_ch;
two_ch max( two_ch a, two_ch b )
{ return (a.ch1>b.ch1) ? a : b; }
%%
Il codice assembly
corrispondente evidenzia che:
max
MOV
ip,sp
STMDB sp!,{a1-a3,fp,ip,lr,pc}
SUB
fp,ip,#4
LDRB a3,[fp,#-&14]
LDRB a2,[fp,#-&10]
CMP a3,a2
SUBLE a2,fp,#&10
SUBGT a2,fp,#&14
LDR
a2,[a2,#0]
STR a2,[a1,#0]
LDMDB fp,{fp,sp,pc}
- * "%
union polymorphic_ptr
{
unsigned a:8, b:8, c:8, d:8;
struct A *a;
struct B *b;
int *i;
}
}
- * $%
- * %%
10
- *
"#
- *
$#
11
- *
%#
Mul64 MOV ip, a1, LSR #16
MOV a4, a2, LSR #16
BIC a1, a1, ip, LSL #16
BIC a2, a2, a4, LSL #16
MUL a3, a1, a2
MUL a2, ip, a2
MUL a1, a4, a1
MUL a4, ip, a4
ADDS ip, a2, a1
ADDCS a4, a4, #&10000
ADDS a1, a3, ip, LSL #16
ADC a2, a4, ip, LSR #16
MOV pc, lr
- *
&#
12
- *
##
Per lesecuzione
> armsd -li multest
A.R.M. Source-level Debugger, version 4.10 (A.R.M.) [Aug 26 1992]
ARMulator V1.20, 512 Kb RAM, MMU present, Demon 1.01, FPE, Little
endian.
Object program file multest
armsd: go
Enter two unsigned 32-bit numbers in hex eg.(100 FF43D)
12345678 10000001
Least significant word of result is 92345678
Most significant word of result is 1234567
Program terminated normally at PC = 0x00008418
0x00008418: 0xef000011 .... : > swi 0x11
armsd: quit
Quitting
>
13