[ บทความ : เรียนรู้ z80 ] ตอนที่ 10 เรื่อง คำสั่งค้นหาข้อมูลในหน่วยความจำ

เรียนรู้ Z80 ตอนที่ 10

คำสั่งค้นหาข้อมูลในหน่วยความจำ

จากสัปดาห์ที่แล้ว เราได้ศึกษาเรื่อง คำสั่งค้นหาข้อมูล ในหน่วยความจำ (แบบเป็นกลุ่ม) ไปแล้ว คราวนี้เราก็ มาดูถึง คำสั่งอีกชุดหนึ่งที่ทำหน้าที่คล้ายๆ กับเรื่องที่แล้ว นั่นก็คือ การค้นหาข้อมูล หรือจะเรียกว่าเป็นการเปรียบเทียบข้อมูล ในรีจิสเตอร์ กับข้อมูลในหน่วยความจำที่เราต้องการ ... คำสั่ง ดังกล่าวคือ CPI, CPIR, CPD, และ CPDR ... (คุ้นไหม) ... ซึ่งรูปแบบของคำสั่งจะเป็นดังนี้ครับ

Instruction
Source/Target
Flag
Operation
CPD
ไม่มี
C
Z (=1 if A=[HL])
H, P/V (=0 if BC=0, =1 if BC <>0)
S (=1 if A < [HL])
N(=1)
HL <- HL-1
BC <- BC-1
CPDR
ไม่มี
C
Z (=1 if A=[HL])
H, P/V (=0 if BC=0, =1 if BC <>0)
S (=1 if A < [HL])
N(=1)
เหมือน CPD แต่ว่า คำสั่งนี้ จะทำการเปรียบเทียบข้อมูล ไปเรื่อยๆ จนกว่า BC จะเป็น 0 หรือ A=[HL]
CPI
ไม่มี
C
Z (=1 if A=[HL])
H, P/V (=0 if BC=0, =1 if BC <>0)
S (=1 if A < [HL])
N(=1)
HL <- HL+1
BC <- BC-1
CPIR
ไม่มี
C
Z (=1 if A=[HL])
H, P/V (=0 if BC=0, =1 if BC <>0)
S (=1 if A < [HL])
N(=1)
เหมือน CPI แต่ว่า คำสั่งนี้ จะทำการเปรียบเทียบข้อมูล ไปเรื่อยๆ จนกว่า BC จะเป็น 0 หรือ A=[HL]
ตาราง 10-1 ชุดคำสั่งสำหรับ ค้นหาข้อมูลแบบกลุ่ม

หมายเหตุ เราต้องเก็บค่าที่เราต้องการค้นหาใน A, เก็บจำนวนครั้งที่ต้องการค้นหาใน BC และ ตำแหน่งเริ่มต้นค้นหาใน HL

ส่วนความแตกต่างระหว่าง CPD กับ CPDR และ CPI กับ CPIR ก็คือ CPD / CPI จะทำเพียงครั้งเดียว แต่ CPDR/ CPIR จะทำเรื่อยๆ จนกว่า BC เป็น 0 หรือ เจอข้อมูลที่จ้องการ ... มาดูตัวอย่างโปรแกรมสำหรับ คำสั่งที่เกี่ยวกับ การแลกเปลี่ยนข้อมูล กันครับ ...


	;
	; Filename : TCPEx.asz
	; Author   : Supachai Budsaratij   (raek@se-ed.net)
	; Date     : Feb 19, 2001
	; Hardware : ET-Board V6 (Z80 Mode)
	;            CP-jr180 (Z180)
	;            ET-Board V5 (Z180)
	;            ET-Board V3.5 New Power (Z80)
	;
	;
	        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:
	        LD      HL,UMEM_ORG+1000h       ; Start search at UMEM_ORG+1000h
	        LD      A,7                     ; Find 7
	        LD      BC,10                   ; Do 10 times.
	        CPIR

	        LD      HL,UMEM_ORG+1000h       ; Start search at UMEM_ORG+1000h
	        LD      A,20                    ; Find 20
	        LD      BC,10                   ; Do 10 times.
	        CPDR
        
	        HALT

	        ORG     UMEM_ORG+1000h
	data    db      1,2,3,4,5,6,7,8,9,10    

		END

เมื่อเราทำการแปลคำสั่งเรียบร้อยแล้ว เราก็จะได้ไฟล์ .LST ดังนี้


                        ;
                        ; Filename : TCPEx.asz
                        ; Author   : Supachai Budsaratij   (raek@se-ed.net)
                        ; Date     : Feb 19, 2001
                        ; Hardware : ET-Board V6 (Z80 Mode)
                        ;            CP-jr180 (Z180)
                        ;            ET-Board V5 (Z180)
                        ;            ET-Board V3.5 New Power (Z80)
                        ;
                        ;
                                INCL    "etv6.inz"         ; Inlude header for ET-V6
                        ;
                        ; filename  : etv6.inz
                        ; assembler : az80
                        ; author    : Supachai Budsaratij (raek@se-ed.net)
                        ; hardware  : et-board 6 (Z-80 mode)
                        ; date      : October 12,2000
                        ;
                        
                        ; --- MEMORY
                        ;
   8000                 UMEM_ORG        EQU     08000h   ; User RAM start
   bdff                 UMEM_END        EQU     0BDFFh   ; User RAM end
   c000                 XMEM_ORG        EQU     0C000h   ; Expand RAM end
   dfff                 XMEM_END        EQU     0DFFFh   ; Expand RAM end
                        
                        ; --- I/O
                        ;
   0000                 S8255_PA        EQU     00h     ; System 8255 port A
   0001                 S8255_PB        EQU     01h     ; System 8255 port B
   0002                 S8255_PC        EQU     02h     ; System 8255 port C
   0003                 S8255_CT        EQU     03h     ; System 8255 control port
                        ;
   0020                 U8255_PA        EQU     20h     ; User 8255 port A
   0021                 U8255_PB        EQU     21h     ; User 8255 port B
   0022                 U8255_PC        EQU     22h     ; User 8255 port C
   0023                 U8255_CT        EQU     23h     ; User 8255 control port
                        ;
   004d                 SCN_INP         EQU     4Dh     ; SCN2681 - Input port (Switch)
   004e                 SCN_SEO         EQU     4Eh     ; SCN2681 - Set output port (LED)
   004f                 SCN_REO         EQU     4Fh     ; SCN2681 - Reset output port (LED)
                        ;
   0060                 CLCD_WC         EQU     60h     ; Character LCD write command
   0061                 CLCD_RC         EQU     61h     ; Character LCD read command
   0062                 CLCD_WD         EQU     62h     ; Character LCD write data
   0063                 CLCD_RD         EQU     63h     ; Character LCD read data
                        ;
   0064                 GLCD_WC1        EQU     64h     ; Graphics LCD write command (Page 1)
   0065                 GLCD_RC1        EQU     65h     ; Graphics LCD read command  (Page 1)
   0066                 GLCD_WD1        EQU     66h     ; Graphics LCD write data    (Page 1)
   0067                 GLCD_RD1        EQU     67h     ; Graphics LCD read data     (Page 1)
                        ;
   0068                 GLCD_WC2        EQU     68h     ; Graphics LCD write command (Page 2)
   0069                 GLCD_RC2        EQU     69h     ; Graphics LCD read command  (Page 2)
   006a                 GLCD_WD2        EQU     6Ah     ; Graphics LCD write data    (Page 2)
   006b                 GLCD_RD2        EQU     6Bh     ; Graphics LCD read data     (Page 2)
                        ;
                        
                        ;        INCL    "etv35.inz"         ; Inlude header for ET-V3.5
                        ;        INCL    "jr180.inz"         ; Inlude header for CP-jr180
                        
   8000                         ORG     UMEM_ORG        ; Start at UMEM_ORG
                        
   8000                 main:
   8000   21 00 90              LD      HL,UMEM_ORG+1000h       ; Start search at UMEM_ORG+1000h
   8003   3e 07                 LD      A,7                     ; Find 7
   8005   01 0a 00              LD      BC,10                   ; Do 10 times.
   8008   ed b1                 CPIR
                        
   800a   21 00 90              LD      HL,UMEM_ORG+1000h       ; Start search at UMEM_ORG+1000h
   800d   3e 14                 LD      A,20                    ; Find 20
   800f   01 0a 00              LD      BC,10                   ; Do 10 times.
   8012   ed b9                 CPDR
                                
   8014   76                    HALT
                        
   9000                         ORG     UMEM_ORG+1000h
   9000   01 02 03 04   data    db      1,2,3,4,5,6,7,8,9,10    
   9004   05 06 07 08   
   9008   09 0a         
                        
   900a                 	END

0061  CLCD_RC       0063  CLCD_RD       0060  CLCD_WC       0062  CLCD_WD   
0065  GLCD_RC1      0069  GLCD_RC2      0067  GLCD_RD1      006b  GLCD_RD2  
0064  GLCD_WC1      0068  GLCD_WC2      0066  GLCD_WD1      006a  GLCD_WD2  
0003  S8255_CT      0000  S8255_PA      0001  S8255_PB      0002  S8255_PC  
004d  SCN_INP       004f  SCN_REO       004e  SCN_SEO       0023  U8255_CT  
0020  U8255_PA      0021  U8255_PB      0022  U8255_PC      bdff  UMEM_END  
8000  UMEM_ORG      dfff  XMEM_END      c000  XMEM_ORG      9000  data      
8000  main          


ส่วนรายละเอียดของไฟล์ฐานสิบหก ก็จะเป็นดังนี้ครับ


	:158000002100903E07010A00EDB12100903E14010A00EDB976A2
	:0A9000000102030405060708090A2F
	:00900A0165

มา debug กันดีกว่าครับ เริ่มตั้งแต่โหลดโปรแกรมเลยนะครับ

แล้วก็เริ่ม trace ด้วยคำสั่ง t 8000 ... คำสั่งแรกเป็นการนำค่า 9000h ไปเก็บใน HL

ต่อมาเราก็นำค่า 7 ไปเก็บใน A ซึ่งมีความหมายว่า เราต้องการค้นหาข้อมูล ที่มีค่า 7

กำหนดให้ BC เป็น 10 เพื่อกำหนดว่า เราจะทำการค้นหากัน 10 ครั้ง

เริ่มการค้นหาด้วย CPIR ซึ่งผลลัพธ์ ออกมาเป็นดังนี้ HL = 9007 เพราะทำไป 7 ครั้ง ... ซึ่งแสดงว่า เราน่าจะเจอข้อมูล หลังจากที่ ทำการเปรียบเทียบไปแล้ว 7 ครั้ง (เพราะเราสั่งให้ทำ 10 ครั้งไง ... แต่ HL ไม่เป็น 900Ah ก็หมายความว่า เจอข้อมูลก่อนไง) ... และ BC เป็น 3 เพราะ ทำไปแค่ 7 ครั้ง .. ส่วน Flag มันก็บอกว่า Z=1 และ S=0 ซึ่ง กรณีที่ Z=1 และ S=0 ก็คือ กรณี ที่ ข้อมูลใน A เท่ากับ ข้อมูลที่ HL ชี้อยู่ ...

คราวนี้ลองให้ HL เป็น 900Ah ดูบ้าง

คราวนี้เราจะหา 14h กันล่ะ

ทำ 10 ครั้งเหมือนเดิม

เอาล่ะ ลองหาแบบ CPDR กันบ้าง ... คราวนี้ผลลัพธ์ คือ HL = 9000h ซึ่ง น่าจะ หมายความว่า ทำไป 10 ครั้ง ... อ้าว BC ก็เป็น 0 เหมือนกัน เอ ... คราวนี้ตกลงว่าหาเจอไหมเนี่ย ... มาดู ที่ Flag กันครับ ... เราพบว่า Z=0 และ S=0 ซึ่ง ไม่ใช่กรณีของ ข้อมูล ใน A เหมือนกับ ข้อมูล ที่ชี้โดย HL ซึ่งหมายความว่า ... ไม่เจอ 14h ในหน่วยความจำตั้งแต่ 9000h-900Ah ...

อ๊ะ ... จบโปรแกรมแล้ว ล่ะ

เรียบร้อยครับ ... เราเรียนรู้เกี่ยวกับการแลกเปลี่ยนข้อมูล , การถ่ายโอนข้อมูล และการค้นหาข้อมูลไปเรียบร้อยแล้วล่ะ ... คราวหน้าเราก็จะศึกษาเกี่ยวกับ การบวก และการลบกันครับ ... แล้วตามด้วย การกระโดด แบบมีเงื่อนไข และไม่มีเงื่อนไขกันต่อ ... หลังจาก 2 เรื่องนี้ผ่านไป เราก็จะสามารถเขียนโปรแกรม ที่มีความซับซ้อนมากๆ ได้แล้วครับ ... เมื่อเริ่มเขียนแบบซับซ้อนได้ เราก็จะต่อ เกี่ยวกับคำสั่งกระทำทาง คำสั่ง I/O, ลอจิก, การกระทำกับบิต, การเลื่อน (shift) / การหมุน (Rotate) บิต, และคำสั่งพิเศษๆ พร้อมทั้ง เทคนิค การเขียนโปรแกรมแบบต่างๆ กับ Z80 กันต่อไป ... ส่วนหลังสุด อาจจะเป็น ข้อมูลเพิ่มเติมเกี่ยวกับ Z180 กัน เพื่อเปิดหูเปิดตาให้กว้าง และใช้ Z80 ในการเขียนโปรแกรมที่ซับซ้อนมากขึ้นเรื่อยๆ ...

นับวัน ผมยิ่งชอบ Z80/Z180 มากขึ้นแล้วสิครับ ... สนุกดีตรงที่มันให้เราเขียนเอง (...ฮา...) แต่ก็ต้องยอมรับครับ ... ส่วนมากผมใช้ MCS-51 แถมสอน หรือ อบรมสมาชิกชุมนุม ucRoboTics ด้วย MCS-51 กับ Micro-C51 อีกด้วย ... แถมหุ่น tracker line ของผม ก็เป็น MCS-51 กับ 68HC11 อีกต่างหากครับ ... อืม ... แล้ว Z80/Z180 ล่ะ ... ผมก็จะพยายาม ใช้มันให้มากขึ้นไงครับ ... และผมก็คงไม่มีบทความเกี่ยวกับ MCS-51 ที่ละเอียด แบบนี้แน่นอนครับ ... เพราะ มีอาจารย์หลายๆ ท่านได้ เขียนตำราเอาไว้มากมาย ... แถมเขียนได้ดีมากๆ ด้วยครับ ลองสืบเสาะหาเอาล่ะกันครับ ... สัปดหานี้เท่านี้ก่อนครับ สวัสดีครับ



เขียนโดย : ศุภชัย บุศราทิจ
Author : Supachai Budsaratij
e-mail : raek@se-ed.net
วันที่ทำการปรับปรุง : ๕ มี.ค. ๒๕๔๔, ๑๓ มี.ค. ๒๕๔๔