Optymalizacja kodu w C dla mikrokontrolera 8051: analiza i przykłady
Re: C do 8051.
From: Radzislaw Galler <rgaller_at_nospam_et.put.poznan.pl>
Subject: Re: C do 8051.
Date: Wed, 02 Feb 2000 11:22:18 GMT
Grzegorz Redlarski wrote:
Przyklad ktory wyslalem tu prawie 3 lata temu (akurat dotyczy to int-a
ale z char-ami jest podobnie):
Przyklad kodu zoptymalizowanego pod wzgledem rozmiaru kodu(opcja size
full -z9).
xdata unsigned int wr;
wr = 0xFF & (wr / 256);
zostalo przekodowane na:
MOV DPTR, #wr
MOVX A, _at_nospam_DPTR
MOV R7, A
INC DPTR
MOVX A, _at_nospam_DPTR
MOV R6, A
MOV A, R7
MOV R5, A
MOV A, R6 ; !!!
MOV A, R5
MOV R5, #0 ; !!!
MOV R4, A ; !!!
MOV R6, A
MOV R7, #0
MOV DPTR, #wr
MOV A, R7
MOVX _at_nospam_DPTR, A
INC DPTR
MOV A, R6
MOVX _at_nospam_DPTR, A
A, mozna by np. tak:
MOV DPTR, #wr
MOVX A, _at_nospam_DPTR
INC DPTR
MOVX _at_nospam_DPTR, A
MOV DPTR, #wr
CLR A
MOVX _at_nospam_DPTR, A
Czesto mozna znalezc w kodzie jakies ladowania do rejestru, ktore
pozniej do niczego nie sa potrzebne. W przykladzie oznaczone zostaly
przez "!!!".
Teraz jest juz chyba troche lepiej.
Twoj przyklad:
------------------
xdata unsigned int wr;
void main(void)
{
wr = 0xFF & (wr /256);
}
-------------------
i po skompilowaniu:
-------------------
##############################################################################
# #
# IAR 8051 C-Compiler V5.40A/WIN #
# #
# Compile time = 02 Feb2000 11:44:13 #
# Target option = 8051 #
# Memory model = tiny #
# Source file = d:\temp\test.c #
# List file = d:\temp\release\list\test.lst #
# Object file = d:\temp\release\obj\test.r03 #
# Command line = -v0 -mt -OD:\Temp\Release\Obj\ -e -K -gA -z9 #
# -RCODE -LD:\Temp\Release\List\ -q -t8 -xDTF2 #
# -ID:\Program Files\IAR\EW\8051\inc\ D:\Temp\test.c #
# #
# (c) Copyright IAR Systems 1998 #
##############################################################################
\ 0000 NAME test(16)
\ 0000 RSEG CODE(0)
\ 0000 RSEG X_UDATA(0)
\ 0000 PUBLIC main
\ 0000 $DEFFN main(0,0,0,0,32768,0,0,0)
\ 0000 PUBLIC wr
\ 0000 EXTERN ?CL8051T_5_40_L17
\ 0000 RSEG CODE
1 xdata unsigned int wr;
2
3 void main(void)
4 {
\ 0000 main:
5 wr = 0xFF & (wr /256);
\ 0000 900000 MOV DPTR,#wr
\ 0003 E0 MOVX A,_at_nospam_DPTR
\ 0004 FE MOV R6,A
\ 0005 A3 INC DPTR
\ 0006 E0 MOVX A,_at_nospam_DPTR
\ 0007 7400 MOV A,#0
\ 0009 900000 MOV DPTR,#wr
\ 000C F0 MOVX _at_nospam_DPTR,A
\ 000D A3 INC DPTR
\ 000E EE MOV A,R6
\ 000F F0 MOVX _at_nospam_DPTR,A
6 }
\ 0010 22 RET
\ 0000 RSEG X_UDATA
\ 0000 wr:
\ 0002 DS 2
\ 0002 END
------------------
ale jeszcze lepiej jest, gdy:
-----------------
xdata unsigned int wr;
void main(void)
{
//wr = 0xFF & (wr /256);
wr >>= 8;
}
wtedy assembler wyglada tak:
---------------------
1 xdata unsigned int wr;
2
3 void main(void)
4 {
\ 0000 main:
5 //wr = 0xFF & (wr /256);
6 wr >>= 8;
\ 0000 900000 MOV DPTR,#wr
\ 0003 E0 MOVX A,_at_nospam_DPTR
\ 0004 F5F0 MOV B,A
\ 0006 E4 CLR A
\ 0007 F0 MOVX _at_nospam_DPTR,A
\ 0008 E5F0 MOV A,B
\ 000A A3 INC DPTR
\ 000B F0 MOVX _at_nospam_DPTR,A
7 }
\ 000C 22 RET
\ 0000 RSEG X_UDATA
\ 0000 wr:
\ 0002 DS 2
\ 0002 END
---------------------
From: Grzegorz Redlarski <gred_at_nospam_kki.net.pl>
Subject: Re: C do 8051.
Date: Fri, 04 Feb 2000 01:13:46 +0100
Wed, 02 Feb 2000 11:22:18 GMT Radzislaw Galler
<rgaller_at_nospam_et.put.poznan.pl> napisal(a):
[...]
Teraz jest juz chyba troche lepiej.
[...]
wr = 0xFF & (wr /256);
i po skompilowaniu:
[...]
No to sie faktycznie poprawili.
[...]
ale jeszcze lepiej jest, gdy:
//wr = 0xFF & (wr /256);
wr >>= 8;
Probowalem roznych sposobow i AFAIR wtedy wychodzilo tak samo.
Ciekawe co by wyszlo z:
wr /= 256;
Tzn., czy roznica wynikla z "0xFF &" czy z zamiany "/" na ">>"?
Takie "& 0xFF" mialem czasem w programie ze wzgledu na wykorzystywane
makra (#define z parametrami) i jesli parametrem byl 0xFF to trafial
sie czasem taki "& 0xFF" z pozoru nie potrzebny.
gr