Group Blog
 
<<
มีนาคม 2554
 12345
6789101112
13141516171819
20212223242526
2728293031 
 
31 มีนาคม 2554
 
All Blogs
 

Assemby VS C (In-depth)

วันนี้ลองมาวัดกันระหว่าง ASM และ C
เริ่มกันที่โจทย์ ง่ายๆ แบบนี้ (ตามรูป)



เปิดฉากด้วย ASM:


org 0x000
jmp start
DISP_CODE: DB 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F
org 0x0100
start:
mov r0,#0
mov a,#DISP_CODE
loop:
clr a
movc a,@a+dptr
inc dptr
mov p0,a
call delay_100ms
inc r0;
mov a,#10
subb a,r0
jnz loop
sjmp start
delay_100ms:
mov r6,#200
  d_100ms:
mov r7,#248
djnz r7,$
djnz r6,d_100ms
mov r7,#97
djnz r7,$
ret
end

ตามติดๆ มาด้วย C:


#include <reg52.h>
char DISP_CODE[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
void delay_100mS(void);
void main(void){
char k;
while(1){
P0=DISP_CODE[k];
delay_100mS();
k++;
if(k>9)k=0;
}
}

void delay_100mS(void){
unsigned char x,y;
for(x=105;x>0;x--){
for(y=245;y>0;y--){
y=y;
}
}
}


ทั้งสองแบบเขียนกันอย่างไม่เข้าข้างใดข้างหนึ่ง นั่นคือตัดเรื่อง optimization ออกไป หรือเขียนแบบจรงไปตรงมานั่นเอง (ด้วยความรู้สึกของผมเอง)

คราวนี้มาดู output กัน:


ของ ASM


:0C00000021003F065B4F666D7D077F6F9F
:1001000078007402E493A3F580311308740A9870A0
:10011000F380ED7EC87FF8DFFEDEFA7F61DFFE222E
:00000001FF

ของ C


:0C00B8000A083F065B4F666D7D077F6FF6
:10008F0074082512F8E6F5801200AA0512D3E512BE
:0B009F006480948A40EAE4F51280E5DA
:0D00AA007F697EF51EEED3940050F9DFF55E
:0100B7002226
:03000000020003F8
:0C000300787FE4F6D8FD75811202004AF7
:10000F0002008FE493A3F8E493A34003F68001F278
:10001F0008DFF48029E493A3F85407240CC8C333F2
:10002F00C4540F4420C8834004F456800146F6DFC1
:10003F00E4800B01020408102040809000B8E47E99
:10004F00019360BCA3FF543F30E509541FFEE493B6
:10005F00A360010ECF54C025E060A840B8E493A37D
:10006F00FAE493A3F8E493A3C8C582C8CAC583CAA8
:10007F00F0A3C8C582C8CAC583CADFE9DEE780BE60
:0100C400003B
:00000001FF

ทั้งของ ASM และ ของ C ไม่มีการใช้ code ในส่วนของ startup ใดๆ มาเกี่ยวข้องทั้งสิ้น หลีกเลี่ยงการใช้ตัวแปลที่ใหญ่กว่า 8 บิต (ใน C) 

มองที่การใช้ RAM (มองรีจิสเตอร์เป็น RAM ด้วย)
   ASM ใช้ไป 2 ไบต์
   C ใช้ไป 20 ไบต์


มองที่ใช้เวลาในการเขียน (วัดเวลาที่ผมเขียนเอง และโปรแกรมถูกวางแผนไว้ในใจมาก่อนแล้ว)
   ASM ใช้เวลาประมาณ 5 นาที
   C ใช้เวลาประมาณ 3 นาที


แล้วจะเลือกอะไรดี?


อย่าตกใจไปครับ จริงๆ C Compiler เขามีอะไรที่ต้องทำอีกมายมายก่อนที่จะวิ่งเข้าส่วนของโปรแกรมที่เราเขียนขึ้น
Code ส่วนนี้จะถูกสร้างขึ้นมาโดยอัตโนมัติ เป็น code ที่ว่าด้วยกำกำหนดค่าเริ่มของ Stack รวมไปถึงส่วนอื่นๆ ที่จำเป็น code ส่วนนี้ C Programmer จะไม่ค่อยสนใจ

หมายรวมไปถึง ASM Programmer บางส่วนด้วยเช่นกัน 


C:0x0000    020003   LJMP     C:0003
C:0x0003 787F MOV R0,#0x7F
C:0x0005 E4 CLR A
C:0x0006 F6 MOV @R0,A
C:0x0007 D8FD DJNZ R0,C:0006
C:0x0009 758112 MOV SP(0x81),#0x12
C:0x000C 02004A LJMP C:004A
C:0x000F 02008F LJMP main(C:008F)
C:0x0012 E4 CLR A
C:0x0013 93 MOVC A,@A+DPTR
C:0x0014 A3 INC DPTR
C:0x0015 F8 MOV R0,A
C:0x0016 E4 CLR A
C:0x0017 93 MOVC A,@A+DPTR
C:0x0018 A3 INC DPTR
C:0x0019 4003 JC C:001E
C:0x001B F6 MOV @R0,A
C:0x001C 8001 SJMP C:001F
C:0x001E F2 MOVX @R0,A
C:0x001F 08 INC R0
C:0x0020 DFF4 DJNZ R7,C:0016
C:0x0022 8029 SJMP C:004D
C:0x0024 E4 CLR A
C:0x0025 93 MOVC A,@A+DPTR
C:0x0026 A3 INC DPTR
C:0x0027 F8 MOV R0,A
C:0x0028 5407 ANL A,#0x07
C:0x002A 240C ADD A,#0x0C
C:0x002C C8 XCH A,R0
C:0x002D C3 CLR C
C:0x002E 33 RLC A
C:0x002F C4 SWAP A
C:0x0030 540F ANL A,#0x0F
C:0x0032 4420 ORL A,#0x20
C:0x0034 C8 XCH A,R0
C:0x0035 83 MOVC A,@A+PC
C:0x0036 4004 JC C:003C
C:0x0038 F4 CPL A
C:0x0039 56 ANL A,@R0
C:0x003A 8001 SJMP C:003D
C:0x003C 46 ORL A,@R0
C:0x003D F6 MOV @R0,A
C:0x003E DFE4 DJNZ R7,C:0024
C:0x0040 800B SJMP C:004D
C:0x0042 0102 AJMP C:0002
C:0x0044 04 INC A
C:0x0045 08 INC R0
C:0x0046 102040 JBC 0x24.0,C:0089
C:0x0049 8090 SJMP C:FFDB
C:0x004B 00 NOP
C:0x004C B8E47E CJNE R0,#0xE4,C:00CD
C:0x004F 0193 AJMP C:0093
C:0x0051 60BC JZ C:000F
C:0x0053 A3 INC DPTR
C:0x0054 FF MOV R7,A
C:0x0055 543F ANL A,#0x3F
C:0x0057 30E509 JNB 0xE0.5,C:0063
C:0x005A 541F ANL A,#0x1F
C:0x005C FE MOV R6,A
C:0x005D E4 CLR A
C:0x005E 93 MOVC A,@A+DPTR
C:0x005F A3 INC DPTR
C:0x0060 6001 JZ C:0063
C:0x0062 0E INC R6
C:0x0063 CF XCH A,R7
C:0x0064 54C0 ANL A,#0xC0
C:0x0066 25E0 ADD A,ACC(0xE0)
C:0x0068 60A8 JZ C:0012
C:0x006A 40B8 JC C:0024
C:0x006C E4 CLR A
C:0x006D 93 MOVC A,@A+DPTR
C:0x006E A3 INC DPTR
C:0x006F FA MOV R2,A
C:0x0070 E4 CLR A
C:0x0071 93 MOVC A,@A+DPTR
C:0x0072 A3 INC DPTR
C:0x0073 F8 MOV R0,A
C:0x0074 E4 CLR A
C:0x0075 93 MOVC A,@A+DPTR
C:0x0076 A3 INC DPTR
C:0x0077 C8 XCH A,R0
C:0x0078 C582 XCH A,DPL(0x82)
C:0x007A C8 XCH A,R0
C:0x007B CA XCH A,R2
C:0x007C C583 XCH A,DPH(0x83)
C:0x007E CA XCH A,R2
C:0x007F F0 MOVX @DPTR,A
C:0x0080 A3 INC DPTR
C:0x0081 C8 XCH A,R0
C:0x0082 C582 XCH A,DPL(0x82)
C:0x0084 C8 XCH A,R0
C:0x0085 CA XCH A,R2
C:0x0086 C583 XCH A,DPH(0x83)
C:0x0088 CA XCH A,R2
C:0x0089 DFE9 DJNZ R7,C:0074
C:0x008B DEE7 DJNZ R6,C:0074
C:0x008D 80BE SJMP C:004D

ต่อไปลองมาดูในส่วนที่เราเขียนขึ้นบ้าง


4: void main(void){ 
     5: char k;
     6: while(1){
     7: P0=DISP_CODE[k];
C:0x008F 7408 MOV A,#DISP_CODE(0x08)
C:0x0091 2512 ADD A,0x12
C:0x0093 F8 MOV R0,A
C:0x0094 E6 MOV A,@R0
C:0x0095 F580 MOV P0(0x80),A
     8: delay_100mS();
C:0x0097 1200AA LCALL delay_100mS(C:00AA)
     9: k++;
C:0x009A 0512 INC 0x12
    10: if(k>10)k=0;
C:0x009C D3 SETB C
C:0x009D E512 MOV A,0x12
C:0x009F 6480 XRL A,#P0(0x80)
C:0x00A1 948A SUBB A,#TL0(0x8A)
C:0x00A3 40EA JC main(C:008F)
C:0x00A5 E4 CLR A
C:0x00A6 F512 MOV 0x12,A
    11: }
    12: }
    13:
C:0x00A8 80E5 SJMP main(C:008F)
    14: void delay_100mS(void){
    15: unsigned char x,y;
    16: for(x=105;x>0;x--){
C:0x00AA 7F69 MOV R7,#0x69
    17: for(y=245;y>0;y--){
C:0x00AC 7EF5 MOV R6,#0xF5
    18: y=y;
    19: }
C:0x00AE 1E DEC R6
C:0x00AF EE MOV A,R6
C:0x00B0 D3 SETB C
C:0x00B1 9400 SUBB A,#0x00
C:0x00B3 50F9 JNC C:00AE
    20: }
C:0x00B5 DFF5 DJNZ R7,C:00AC
    21: }

เอาหละ... เริ่มหวั่น แล้วตกลงมันยังไงกันล่ะทีนี้

งั้นเข้าไปเจาะให้ลึกลงไปอีก เอาที่แบบเป็น Machine code จริงๆ เลย (ตัดความเป็น Intel Format ออกไป)


ของ ASM


210078007402E493A3F580311308740A9870A0F380ED7EC87FF8DFFEDEFA7F61DFFE22

ของ C


02008F74082521F8E6F5801200AA0512D3Ed126480948A40EAE4F51280E57F697EF51EEED3940050F9DFF5

ชัดเจนครับ ตอนนี้ว่ากันที่เนื้อแท้ของ Machine code จะเห็นว่า C ยาวกว่าไป 7 ไบต์ (ย้ำนะครับ ทั้งหมดเขียนแบบตรงไปตรงไปตรงมาไม่มีการ optimize ทั้งใน ASM และ C)


ความคิดของโปรแกรมเมอร์ยุคเก่า (ที่เก๋าพอตัว) ยังคงเป็นจริงต่อไปว่า C ไม่มีทางจะสู้ ASM ได้เลย ตรงนี้ก็ต้องพิจารณากันเอาเองครับ ผมไม่มีความเห็นใดๆ

แต่.... อย่างไรก็คุณผู้อ่านอย่าได้ไปท้าทายกับมือฉมังด้าน ASM หรือ C เพื่อจะวัดอะไรบางอย่างเป็นอันขาด เพราะการเขียน Code ในระดับ Optimization ทั้งใน ASM  และ C
มันมีอะไรน่ากลัวและน่าทึ่งมากกว่าที่เราๆ ท่านๆรู้จักกันมากนัก
แต่ถ้าวัดกันจริงๆ การ Optimize ของผู้เชี่ยวชาญด้าน ASM นั้น C Programmer และ C Compiler ที่ดีที่สุดในโลกก็ไม่มีทางจะสู้ได้ทั้งในแง่ของความเร็ว และขนาดของ Machine code
แต่...เวลาในการเขียนโปรแกรมขนาดใหญ่ๆ ASM แพ้ไม่เป็นท่าแน่นอน


จะยังไงก็ตาม ด้วยข้อด้อยและข้อดี ของทั้งสองตัว มันก็เลยทำให้ผม และใครๆ หลายต่อหลายคน ไม่สามารถละได้ทั้ง ASM และ C ออกไปจากชีวิตได้ !!
โดยเฉพาะเมื่ออยู่ในโลกของ Embedded System



บทความนี้สรุปว่า รักพี่เสียดายน้อง




By Santi; //www.shadowwares.com




 

Create Date : 31 มีนาคม 2554
0 comments
Last Update : 31 มีนาคม 2554 9:41:58 น.
Counter : 1026 Pageviews.


TheInsight
Location :


[ดู Profile ทั้งหมด]

ฝากข้อความหลังไมค์
Rss Feed
Smember
ผู้ติดตามบล็อก : 3 คน [?]




Links
 

 Pantip.com | PantipMarket.com | Pantown.com | © 2004 BlogGang.com allrights reserved.