|
| 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | |
|
|
|
|
|
|
|
การเขียนฟังก์ชั่นแบบ memcpy ในภาษาซี
ฟังก์ชั่น memcpy จริง ๆ มีอยู่ใน standard library ของ C ในส่วนของ string.h แต่งวดนี้ ทางที่ทำงาน อยากได้แบบไม่ต้อง include library ตัวนี้ ดังนั้นก็ต้องเขียนใหม่เลย
การเขียนนี้ ต้องระวังเรื่องขนาดของ CPU ว่าเป็นแบบกี่บิต เช่นที่ผมใช้ เป็นแบบ 32 บิต นั่นหมายถึง มันสามารถ access ทีนึงได้ 32 บิต หรือ 4 ไบต์
และสิ่งที่ต้องระวังอีกส่วนที่หัวหน้าสอนคือ การเข้าถึงตำแหน่ง address ถ้าตำแหน่งนั้น ไม่สามารถ access ได้ 4 ไบต์ ต้องค่อย ๆ access ทีละ 1 ไบต์ หรือ 2 ไบต์ ไม่ก็ต้องทำทั้งสองอย่าง
เช่น ถ้า ข้อมูลเริ่มตำแหน่งที่ address -> 100 นั่นก็แสดงว่า ระบบสามารถ access ทีละ 4 ไบต์ได้ทันที
แต่ถ้าเริ่มต้นที่ 101 จะ access ไม่ได้ ต้องอ่านแบบ 1 ไบต์ก่อน แล้วค่อยอ่านแบบ 2 ไบต์ เพื่อที่จะให้ address ขยับไปที่ตำแหน่ง 104
แต่ถ้าเริ่มต้นที่ 102 ก็ access 2 ไบต์ ก็พอ และถ้าเริ่มต้นที่ 103 ก็ access เพียง 1 ไบต์ ก็ข้ามไปที่ 4 ไบต์ได้เลย
และสุดท้ายจุดที่ต้องระวังคือ จำนวนที่จะก๊อปปี้ นั่นคือ ถ้าเราต้องการก๊อปปี้เพียง 40 ตำแหน่ง และมันเริ่มต้นที่ address 100 ก็ก๊อปปี้ทีละ 4 ไบต์ได้เลย ทำงานเพียง 10 รอบ ก็จบ
แต่ถ้า เริ่มต้นที่ 100 และก๊อป 37 ตำแหน่ง มันจะก๊อป 4 ไบต์ 9 รอบ (36 ตำแหน่ง) และจะก๊อป 1 ไบต์ 1 รอบ ซึ่งรวมแล้ว 10 รอบ
แต่ถ้าเริ่มต้นที่ 100 และก๊อป 38 ตำแหน่ง มันจะก๊อป 4 ไบต์ 9 รอบ (36 ตำแหน่ง) และจะก๊อป 2 ไบต์ 1 รอบ ซึ่งรวมแล้ว 10 รอบ
แต่ถ้าเริ่มต้นที่ 100 และก๊อป 39 ตำแหน่ง มันจะก๊อป 4 ไบต์ 9 รอบ (36 ตำแหน่ง) และจะก๊อป 2 ไบต์ 1 รอบ และจะก๊อป 1 ไบต์ 1 รอบ ซึ่งรวมแล้ว 11 รอบ
แต่ถ้าเริ่มต้นที่ 101 และก๊อปปี้ 40 ตำแหน่งละก็ จะทำงาน ก๊อปปี้ 1 ไบต์ และขยับ address 1 ไบต์ ก๊อปปี้ 2 ไบต์ และขยับ address 2 ไบต์ ก๊อปปี้ 4 ไบต์ รวม 9 รอบ ก๊อปปี้ 1 ไบต์ รวม 1 รอบ เบ็ดเสร็จ ต้องก๊อปปี้รวม 13 รอบ
เห็นความยุ่งยากของการเขียนโปรแกรมหรือยังครับ
ยิ่งถ้าซีพียูเป็นแบบ 64 บิต แล้วมีข้อแม้เยอะด้วยหละก็ เขียนโปรแกรมมึนเลย ฮ่าฮ่า 
----- มาดูโค้ดกันดีกว่า -----
ส่วน memcpy.h
typedef unsigned char uchar8; typedef unsigned short uint16; typedef unsigned long uint32; void memcpy(uchar8 * dest,const uchar8 * src, uint16 remain_byte);
ส่วน memcpy.c
#include "memcpy.h"
void memcpy(uchar8 * dest,const uchar8 * src, uint16 remain_byte) { if (((uint32)src & (uint32)0x01) == 1) /* ((uint32)src % 2) == 1 */ { *((uchar8 *)dest) = *((uchar8 *)src); src++; dest++; remain_byte--; }
if (((uint32)src & (uint32)0x02 ) == 2) /* ((uint32)src % 4) == 2 */ { *((uint16 *)dest) = *((uint16 *)src); src += 2; dest += 2; remain_byte -= 2; } for (i=0; i < (remain_byte >> 2); i++) /* remain_byte / 4 */ { /* Long_Copy */ *((uint32 *)dest) = *((uint32 *)src); src += 4; dest += 4; } if ((remain_byte & (uint16)0x02) == 2) /* remain_byte % 4 */ { /* Word_Copy */ *((uint16 *)dest) = *((uint16 *)src); src += 2; dest += 2; } if ((remain_byte & (uint16)0x01) == 1) /* remain_byte % 2 */ { /* Byte_Copy */ *((uchar8 *)dest) = *((uchar8 *)src); src++; dest++; } }
โปรแกรมด้านบน ยังมีบั๊กในส่วนการเขียนข้อมูลนะครับ ถ้าตำแหน่ง Address ไม่สามารถจะเขียนได้ทีละ 4 byte ข้อมูลอาจจะหายได้ครับ ไว้จะมาอัพเดทตัวที่ทำงานได้จริง ๆ ครับ
Create Date : 07 กันยายน 2550 |
Last Update : 21 มีนาคม 2551 2:11:43 น. |
|
0 comments
|
Counter : 3012 Pageviews. |
 |
|
|
|
|
|
|