[ บทความ : เรียนรู้ z80 ] ตอนที่ 8 เรื่อง คำสั่งที่เกี่ยวการแลกเปลี่ยนข้อมูล |
เรียนรู้ Z80 ตอนที่ 8
คำสั่งที่เกี่ยวกับ การแลกเปลี่ยนข้อมูล
สวัสดีครับ หายไปหลายสัปดาห์เลยสำหรับบทความเรื่อง Z80 ... (มัวทำงานส่งอาจารย์อยู่) ในสัปดาห์นี้ จะเป็น เรื่องของคำสั่งที่เกี่ยวกับการแลกเปลี่ยนข้อมูล ... การแลกเปลี่ยนข้อมูล หรือที่เรียกกันว่า Exchange นั้น มีหลักการทำงาน อยู่ว่า เราจะเอาค่าที่เก็บจากที่หนึ่ง ไปเก็บเอาไว้ ณ อีกที่หนึ่ง และนำค่า จากที่ที่เราเอาค่าไปเก็บนั้น มาเก็บในค่าเริ่มต้น (งงไหมครับ ... งงล่ะสิ :-D) ... มาดูตัวอย่างดีกว่าครับ ... สมมติว่า เราให้ตัวแปร A เก็บค่า 50 และตัวแปร B เก็บค่า 30 ดังนั้น เมื่อเราทำการแลกเปลี่ยนค่า ก็จะได้ผลลัพธ์ ออกมาว่า ที่ตัวแปร A นั้น จะเก็บค่า 30 และ ที่ตัวแปร B ก็จะเก็บค่า 50 เอาไว้ ... (พอจะเข้าใจไหมครับ...)
ว่าแล้ว เรามาดูรูปแบบของคำสั่งแลกเปลี่ยนข้อมูล หรือ Exchange กันดีกว่า
ตาราง 8-1 ชุดคำสั่งสำหรับ Exchange
Instruction Source/Target Flag Operation EX AF, AF' - AF <-> AF' EX DE, HL - DE <-> HL EX (SP), HL - (SP) <-> HL EX (SP), IX - (SP) <-> IX EX (SP), IY - (SP) <-> IY EXX - BC <-> BC'
DE <-> DE'
HL <-> HL'
จากตาราง 8-1 จะเห็นว่า เราสามารถทำการสลับค่าระหว่าง ข้อมูลในรีจิสเตอร์ หรือ ข้อมูลใน stack (บทความเกี่ยวกับ stack) กับ รีจิสเตอร์ ได้เท่านั้น ที่นอกเหนือไปจากนี้ เราคงต้องอาศัยการเขียนโปรแกรม ขึ้นมาเอง ....
มาดูตัวอย่างโปรแกรมสำหรับ คำสั่งที่เกี่ยวกับ การแลกเปลี่ยนข้อมูล กันครับ ...
; ; Filename : TExch.asz ; Author : Supachai Budsaratij (raek@se-ed.net) ; Date : Jan 18, 2000 ; Hardware : ET-Board V6 (Z80 Mode) ; CP-jr180 ; ET-Board V5 ; ET-Board V3.5 New Power ; ; ; INCL "etv6.inz" ; Inlude header for ET-V6 ; INCL "etv35.inz" ; Inlude header for ET-V3.5 INCL "jr180.inz" ; Inlude header for CP-jr180 ORG UMEM_ORG ; Start at UMEM_ORG main: ; --- My code here LD A,0FFh ; A = FFh LD BC,0F110h ; BC = F110h LD DE,10FAh ; DE = 10FAh LD HL,2301h ; HL = 2301h EX AF,AF' ; AF <-> AF' EX DE,HL ; DE <-> HL (Now HL equal to 10FAh and DE equal to 2301h) EX (SP),HL ; (SP) <-> HL EX (SP),IX ; (SP) <-> IX EX (SP),IY ; (SP) <-> IY EXX ; BC <-> BC', DE <-> DE' and HL <-> HL' ; ---End of program HALT ENDเมื่อเราทำการแปลคำสั่งเรียบร้อยแล้ว เราก็จะได้ไฟล์ .LST ดังนี้
; ; Filename : TExch.asz ; Author : Supachai Budsaratij (raek@se-ed.net) ; Date : Jan 18, 2000 ; Hardware : ET-Board V6 (Z80 Mode) ; CP-jr180 ; ET-Board V5 ; ET-Board V3.5 New Power ; ; ; INCL "etv6.inz" ; Inlude header for ET-V6 ; INCL "etv35.inz" ; Inlude header for ET-V3.5 INCL "jr180.inz" ; Inlude header for CP-jr180 ; ; filename : jr180.inz ; assembler : az80 ; author : Supachai Budsaratij (raek@se-ed.net) ; hardware : CP-jr180 Plus ; date : Dec 5, 2000 ; ; Note : Must use jr180 debugger. ; ; --- MEMORY (Logical address) ; 8000 UMEM_ORG EQU 08000h ; User RAM start (10000h - Physical address) ffff UMEM_END EQU 0FFFFh ; User RAM end (17FFFh - Physical address) ; ; --- MEMORY (Physical address) 0000 P_UMEM_ORG EQU 10000h 7fff P_UMEM_END EQU 17FFFh 8000 P_XMEM_ORG EQU 018000h ; Expand RAM end ffff P_XMEM_END EQU 01FFFFh ; Expand RAM end ; --- I/O ; 0080 U8255_PA EQU 80h ; User 8255 port A 0081 U8255_PB EQU 81h ; User 8255 port B 0082 U8255_PC EQU 82h ; User 8255 port C 0083 U8255_CT EQU 83h ; User 8255 control port ; ; --- for Character LCD 00c0 CLCD_WC EQU 0C0h ; Write instruction to LCD 00c2 CLCD_WD EQU 0C2h ; Write data to CG or DD RAM 00c4 CLCD_RD EQU 0C4h ; Read busy flag and address ; --- for Graphics LCD 00c0 GLCD_WC EQU 0C0h ; Write instruction to LCD (Page1) 00c1 GLCD_WC2 EQU 0C1h ; Write instruction to LCD (Page2) 00c2 GLCD_WD EQU 0C2h ; Write data to CG or DD RAM (Page1) 00c3 GLCD_WD2 EQU 0C3h ; Write data to CG or DD RAM (Page2) 00c4 GLCD_RD EQU 0C4h ; Read busy flag and address (Page1) 00c5 GLCD_RD2 EQU 0C5h ; Read busy flag and address (Page2) ; 00e0 WATCH_DOG EQU 0E0h 8000 ORG UMEM_ORG ; Start at UMEM_ORG 8000 main: ; --- My code here 8000 3e ff LD A,0FFh ; A = FFh 8002 01 10 f1 LD BC,0F110h ; BC = F110h 8005 11 fa 10 LD DE,10FAh ; DE = 10FAh 8008 21 01 23 LD HL,2301h ; HL = 2301h 800b 08 EX AF,AF' ; AF <-> AF' 800c eb EX DE,HL ; DE <-> HL (Now HL equal to 10FAh and DE equal to 2301h) 800d e3 EX (SP),HL ; (SP) <-> HL 800e dd e3 EX (SP),IX ; (SP) <-> IX 8010 fd e3 EX (SP),IY ; (SP) <-> IY 8012 d9 EXX ; BC <-> BC', DE <-> DE' and HL <-> HL' ; ---End of program 8013 76 HALT 8014 END 00c4 CLCD_RD 00c0 CLCD_WC 00c2 CLCD_WD 00c4 GLCD_RD 00c5 GLCD_RD2 00c0 GLCD_WC 00c1 GLCD_WC2 00c2 GLCD_WD 00c3 GLCD_WD2 7fff P_UMEM_END 0000 P_UMEM_ORG ffff P_XMEM_END 8000 P_XMEM_ORG 0083 U8255_CT 0080 U8255_PA 0081 U8255_PB 0082 U8255_PC ffff UMEM_END 8000 UMEM_ORG 00e0 WATCH_DOG 8000 mainส่วนรายละเอียดของไฟล์ฐานสิบหก ก็จะเป็นดังนี้ครับ
:148000003EFF0110F111FA1021012308EBE3DDE3FDE3D97608 :008014016Bคราวนี้ ลองเอาโปรแกรมไปทดสอบด้วยการ debug (step หรือ trace) แบบทีละคำสั่งดูสิครับ ... แล้ว ลอง บอกกับตัวเองดูสิครับว่า ได้ผลลัพธ์ ของ AF, AF', BC, BC', DE, DE', HL, HL', IX และ IY เป็นเท่าไร ... ถ้าไม่รู้ว่าจะต้องทำการ ทำงานทีละคำสังอย่างไร ก็อ่านได้จากบทความก่อนหน้านี้ครับ ...
ตอนนี้คำสั่งเกี่ยวกับ การแลกกเปลี่ยนข้อมูล ก็จบลงเท่านี้ครับ ... จะเห็นว่า คำสั่งนี้มีประโยชน์ ในเรื่อง การสลับค่าไปมาระหว่าง รีจิสเตอร์หลัก และรีจิสเตอร์สำรอง ซึ่ง เป็นทางเลือกหนึ่งสำหรับ การเก็บค่าเดิมที่เก็บ ในรีจิสเตอร์หลัก แทนการใช้ stack แต่อย่างไรก็ตาม อย่างที่ผมได้เกริ่นเอาไว้ ตอนต้น ว่า ถ้าเราจะสลับ หรือ แลกเปลี่ยนข้อมูล ที่อยู่ในหน่วยความจำ เราก็ต้องอาศัยการใช้ stack ก็เป็นทางเลือกที่ดีอีกทางหนึ่ง .... ต่อไปนี้ บทความผมคงเป็นในลักษณะ อธิบานคำสั่ง ยกตัวอย่างโปรแกรม และตามด้วยคำถาม อีกเล็กน้อย เพื่อ ผู้อ่านจะได้ทดลองดูบ้างครับ ... บอกหมดไปทีเดียว มันไม่เร้าใจ .. จริงไหมครับ ... (:-D) ... คราวหน้าเป็นเรื่องการ แบบเป็นบล็อก ครับ ...