[ บทความ : มาเขียนโปรแกรมกับ 68HC11 กันเถอะ ตอนที่ 9 ]  คำสั่งเกี่ยวกับการเลื่อนบิตและการหมุนบิต

 

                

               

            สวัสดีครับ บทความคราวนี้เป็นเรื่องของชุดคำสั่งเกี่ยวกับการหมุนและเลื่อนบิต ซึ่งการทำงานของทั้งสองชนิดนี้จะแตกต่างกันตรงที่ว่า การเลื่อนบิตนั้นจะทำให้ข้อมูลเก่าหายไป และนำค่า 0 มาแทนที่ แต่การหมุนบิต จะนำค่าของบิตที่หายไปมาใส่ แทนที่บิตที่ถูกเลื่อนไป … มองภาพไม่ออกใช่ไหมครับ … มาดูการทำงานของการเลื่อนบิตแบบคร่าวๆ กันก่อนครับ

        การเลื่อนบิต

        ถ้าเรามีข้อมูลขนาด 8 บิต เก็บค่าเลขฐานสองเป็น 11110101 แล้วเราสั่งให้มีการเลื่อนบิตไปทางซ้าย การทำงานจะเป็นดังรูปที่ 1 ครับ นั่นคือ บิตทางซ้ายสุดจะถูกดันออกไป แล้วบิตทางขวาสุดก็จะว่าง ดังนั้น ค่าที่จะถูกนำมาใส่จึงเป็น 0 ผลของการทำงานจึงได้เป็นค่าเลขฐานสองเป็น 11101010  ส่วนการเลื่อนบิตไปทางขวานั้น จะคล้ายกันแต่เปลี่ยนเป็นนำค่าบิตทางขวาออก แล้วบิตทางซ้ายสุดก็จะว่าง เราก็จะนำค่า 0 ไปใส่ นั่นเอง

 

รูปที่1   การเลื่อนบิต

           การหมุนบิต

            การหมุนบิตก็จะคล้ายกับการเลื่อนบิต แต่ช่วงที่เราบิตทางซ้ายหรือทางขวาออกไปนั้น เราก็จะนำค่าไปใส่ในบิตทางว่างอยู่ ดังตัวอย่างรูปที่ 2 ซึ่งเป็นการหมุนบิตไปทางซ้าย  

รูปที่ 2   การหมุนบิต

จุดประสงค์

          ศึกษารูปแบบและการทำงานของคำสั่งเลื่อนบิตและหมุนบิต

คำสั่ง/รูปแบบและผลการทำงาน             

            จากตัวอย่างของเลื่อนบิตและการหมุนบิต ตัวข้อมูลที่ถูกเลื่อนออกจากข้อมูลใน 8 บิต นั้น จะถูกนำไปเก็บเอาไว้ในบิตทด (บิต C)

             คำสั่งสำหรับการหมุนบิต                  

RORA

รูปแบบ RORA
ผลต่อ CCR N, Z, V, C
หน้าที่   ทำการหมุนบิตของเรจิสเตอร์ A ไปทางขวา 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นใส่เอาไว้ในบิตทด แล้วนำค่าจากบิตทดมาเติมในช่องว่าง
   

RORB

รูปแบบ RORB
ผลต่อ CCR N, Z, V, C
หน้าที่   ทำการหมุนบิตของเรจิสเตอร์ B ไปทางขวา 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นใส่เอาไว้ในบิตทด แล้วนำค่าจากบิตทดมาเติมในช่องว่าง
   
ROR
รูปแบบ ROR       opr
ผลต่อ CCR N, Z, V, C
หน้าที่   ทำการหมุนบิตของ opr ไปทางขวา 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นใส่เอาไว้ในบิตทด แล้วนำค่าจากบิตทดมาเติมในช่องว่าง โดยที่ opr นั้นจะเป็นการอ้างอิงถึงเรจิสเตอร์ A,B หรือหน่วยความจำ
   

ROLA

รูปแบบ ROLA
ผลต่อ CCR N, Z, V, C
หน้าที่   ทำการหมุนบิตของเรจิสเตอร์ A ไปทางซ้าย  1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นใส่เอาไว้ในบิตทด แล้วนำค่าจากบิตทดมาเติมในช่องว่าง
   
ROLB
รูปแบบ ROLB
ผลต่อ CCR N, Z, V, C
หน้าที่   ทำการหมุนบิตของเรจิสเตอร์ B ไปทางซ้าย  1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นใส่เอาไว้ในบิตทด แล้วนำค่าจากบิตทดมาเติมในช่องว่าง
   
ROL
รูปแบบ ROL       opr
ผลต่อ CCR N, Z, V, C
หน้าที่   ทำการหมุนบิตของ opr ไปทางซ้าย 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นใส่เอาไว้ในบิตทด แล้วนำค่าจากบิตทดมาเติมในช่องว่าง โดยที่ opr นั้นจะเป็นการอ้างอิงถึงเรจิสเตอร์ A,B หรือหน่วยความจำ
   

    

         คำสั่งเลื่อนบิตแบบลอจิก (Logic)     

LSLA
รูปแบบ LSLA
ผลต่อ CCR N, Z, V, C
หน้าที่   เลื่อนบิตของเรจิสเตอร์ A ไปทางซ้าย 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและและเติมค่า 0 ให้แก่บิตที่ว่าง
   

LSLB

รูปแบบ LSLB
ผลต่อ CCR N, Z, V, C
หน้าที่  

เลื่อนบิตของเรจิสเตอร์ B ไปทางซ้าย 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและและเติมค่า 0 ให้แก่บิตที่ว่าง

   
LSL
รูปแบบ LSL        opr
ผลต่อ CCR N, Z, V, C
หน้าที่   เลื่อนบิต ไปทางซ้าย 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและและเติมค่า 0 ให้แก่บิตที่ว่าง ซึ่ง opr นั้นจะเป็นเรจิสเตอร์ A,B หรือหน่วยความจำ
   
LSLD
รูปแบบ LSLD
ผลต่อ CCR N, Z, V, C
หน้าที่  

เลื่อนบิตของเรจิสเตอร์ D ไปทางซ้าย 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและและเติมค่า 0 ให้แก่บิตที่ว่าง

   
LSRA
รูปแบบ LSRA
ผลต่อ CCR N=0, Z, V, C
หน้าที่   เลื่อนบิตของเรจิสเตอร์ A ไปทางขวา 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและและเติมค่า 0 ให้แก่บิตที่ว่าง
   

LSRB

รูปแบบ LSRB
ผลต่อ CCR N=0, Z, V, C
หน้าที่  

เลื่อนบิตของเรจิสเตอร์ B ไปทางขวา 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและและเติมค่า 0 ให้แก่บิตที่ว่าง

   
LSR
รูปแบบ LSR        opr
ผลต่อ CCR N=0, Z, V, C
หน้าที่   เลื่อนบิต ไปทางขวา 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและและเติมค่า 0 ให้แก่บิตที่ว่าง ซึ่ง opr นั้นจะเป็นเรจิสเตอร์ A,B หรือหน่วยความจำ
   
LSRD
รูปแบบ LSRD
ผลต่อ CCR N=0, Z, V, C
หน้าที่   เลื่อนบิตของเรจิสเตอร์ D ไปทางขวา 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและและเติมค่า 0 ให้แก่บิตที่ว่าง
   

      

            คำสั่งเลื่อนบิตแบบเลขคณิต (Arithmetic)

ASLA
รูปแบบ ASLA
ผลต่อ CCR N, Z, V, C
หน้าที่   เลื่อนบิตของเรจิสเตอร์ A ไปทางซ้าย 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและเติมค่า 0 ให้แก่บิตที่ว่าง
   

ASLB

รูปแบบ ASLB
ผลต่อ CCR N, Z, V, C
หน้าที่   เลื่อนบิตของเรจิสเตอร์ B ไปทางซ้าย 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและเติมค่า 0 ให้แก่บิตที่ว่าง
   
ASL
รูปแบบ ASL       opr
ผลต่อ CCR N, Z, V, C
หน้าที่   เลื่อนบิตไปทางซ้าย 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและเติมค่า 0 ให้แก่บิตที่ว่าง โดยที่ opr เป็นเรจิสเตอร์ A/B หรือ หน่วยความจำ
   
ASLD
รูปแบบ ASLD
ผลต่อ CCR N, Z, V, C
หน้าที่   เลื่อนบิตของเรจิสเตอร์ D ไปทางซ้าย 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทดและเติมค่า 0 ให้แก่บิตที่ว่าง
   

ASRA

รูปแบบ ASRA
ผลต่อ CCR N, Z, V, C
หน้าที่   เลื่อนบิตของเรจิสเตอร์ B ไปทางขวา 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทด แต่ค่าของบิตทางซ้ายสุดจำไม่มีการเปลี่ยนแปลง
   

ASRB

รูปแบบ ASRB
ผลต่อ CCR N, Z, V, C
หน้าที่   เลื่อนบิตของเรจิสเตอร์ B ไปทางขวา 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทด แต่ค่าของบิตทางซ้ายสุดจำไม่มีการเปลี่ยนแปลง
   
ASR
รูปแบบ ASR       opr
ผลต่อ CCR N, Z, V, C
หน้าที่   เลื่อนบิต ไปทางขวา 1 ครั้ง โดยนำค่าที่เลื่อนไปนั้นไปเก็บในบิตทด แต่ค่าของบิตทางซ้ายสุดจำไม่มีการเปลี่ยนแปลง และค่าของ opr อาจจะเป็นเรจิสเตอร์ A/B หรือหน่วยความจำ
   

 

   สรุป

                 ตอนนี้เราได้เรียนรู้รูปแบบและการทำงานของคำสั่งเกี่ยวกับการเลื่อนบิตและหมุนบิตกันไปแล้ว ถ้าเราสังเกตจะพบว่าประโยชน์อีกอย่างหนึ่งของการเลื่อนบิตก็คือ ถ้าเราสั่งให้เลื่อนบิตไปทางซ้ายจำนวน 1 บิต มันจะเหมือนกับการนำค่าเดิมของข้อมูลนั้นคูณด้วยสอง และในทางกลับกัน ถ้าเราเลื่อนบิตไปทางขวา ผลของการทำงานจะเห็นกับการนำค่าตัวเลขนั้นมาหารด้วยสอง … คราวหน้าจะเป็นคำสั่งเกี่ยวกับการบวก/ลบ และครั้งต่อๆไปก็จะเป็นการคูณ/หาร และลงท้ายด้วยคำสั่งเกี่ยวกับลอจิก …แล้วเราก็จะเหลือคำสั่งอีก 2 กลุ่ม คือ คำสั่งเกี่ยวกับการกระโดด ซึ่งมีด้วยกันหลายแบบ กับคำสั่งควบคุมการทำงานของ CPU เท่านี้ชุดคำสั่งของ 68HC11 ก็จะหมดลงแล้วครับ … หลังจากหมดเรื่องของชุดคำสั่ง ถ้าผมไม่เปลี่ยนไปศึกษาเรื่องชุดคำสั่งของ CPU ตัวอื่น ก็จะมาอธิบายเรื่องการควบคุม I/O ของ 68HC11 กันต่อล่ะกันครับ ทั้งนี้ที่ไม่รับปากว่าจะลงเรื่อง I/O หรือไม่นั้น เป็นเพราะ ผมเองซื้อบอร์ดไมโครคอนโทรลเลอร์เอาไว้หลายรุ่นมากครับ ที่ยังไม่ได้กล่าวถึงเลยยังมีอีก 3 ตัว คือ BASIC Stamp, 68HC08 และ AVR ส่วน MCS-51 นั้นอย่างไรคงค่อยแยกเนื้อหาของชุดคำสั่งมาลงให้ครับ เนื่องจากหนังสือที่เขียนไว้นั้นยังไม่ได้ทำต่อ เลยคาดว่าจะนำมาเขียนเป็นตอนแล้วลงเป็นบทความท่าทางจะมีประโยชน์ดีเหมือนกัน … ขอให้มีความสุขกับการศึกษาหาความรู้ครับ ...

  


เขียนโดย : ศุภชัย  บุศราทิจ
Author : Supachai  Budsaratij
วันที่ทำการปรับปรุง : ๒๖ มิ.ย. ๒๕๔๖