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

 

                

                ตามสัญญาครับ บทความตอนนี้จะเป็นคำสั่งเกี่ยวกับสแตก ... แล้วเจ้าสแตกมันคืออะไร? คำตอบก็คือ มันก็เป็นหน่วยความจำล่ะครับ เพียงแต่ว่าลักษณะการทำงานของมันนั้น เขาออกแบบไว้ว่า จะต้องทำงานแบบ เข้าก่อนออกทีหลัง หรือ ที่เรียกว่า Last In First Out (LIFO) และสิ่งที่เราจะทำกับหน่วยความจำสแตกได้นั้น มีเพียง 2 อย่าง คือ การ PUSH และ POP โดยที่

การ PUSH นั้นจะเป็นกระบวนการนำข้อมูลใส่เข้าไปในหน่วยความจำสแตก โดยการใส่เข้าไปนั้น ของใหม่จะซ้อนอยู่บนข้อมูลเก่า ถ้านึกภาพไม่ออก ก็ขอให้นึกถึงลักษณะของการวางหนังสือซ้อนกันนะครับ เล่มแรกที่เราวางลงไปนั้นจะอยู่ด้านล่าง และเล่มต่อไปที่เราจะวางซ้อนก็จะอยู่บนหนังสือเล่มก่อนหน้านั้น ลักษณะอย่างนี้และหรับที่เรียกว่าการ PUSH ข้อมูล และกองหนังสือนั้นก็คือสแตก นั่นเอง ยิ่งถ้าเราบอกว่า สแตกนั้นสามารถวางซ้อนกันได้ 8 ระดับ ก็หมายความว่า เราสามารถวางหนังสือซ้อนกันได้เพียง 8 เล่ม ถ้าจะใส่เล่มที่ 9 ก็จะเกิดสิ่งที่เรียกว่า Stack Overflow หรือเรียกกันว่า สแตกเต็ม ... แต่อย่างไรก็ดี เวลาเกิด Stack Overflow นั้น พวกไมโครคอนโทรลเลอร์มักจะนำข้อมูลใส่ในตำแหน่งถัดไปของหน่วยความจำ หรือไม่ก็วกกลับมาที่ตำแหน่งเริ่มต้น อันนี้เราต้องระวังให้ดีครับ ไม่เช่นนั้น จะเกิดปัญหาอีกเยอะเลยล่ะ

 

การ POP เป็นการกระทำที่ตรงกันข้ามกับ PUSH นั่นคือ การ POP จะเป็นการนำข้อมูลออกจากสแตก เมื่อเรานำข้อมูลออกมาแล้ว ข้อมูลในสแตกก็จะลดลง เช่น เดิมมี 8 ชั้น พอเรา pop มันก็จะเหลือ 7 ชั้น ยิ่งเรา pop ออกมาเรื่อยๆ จนหมดข้อมูลแล้วเรายังดันทุรังจะ pop ออกอีก ก็จะเกิดเหตุการณที่เรียกว่า Stack Underflow หรือ สแตกนั้นว่าง

 

 

                การประยุกต์ใช้ Stack นั้นมีอยู่เยอะมากครับ ไม่ว่าจะเป็นการฝากค่าตำแหน่งของหน่วยความจำ ที่จะต้องทำการประมวลผลหลังจากที่เรียกโปรแกรมย่อย , ใช้ฝากข้อมูลชั่วคราว เพราะเรจิสเตอร์นั้น มีให้เราใช้ไม่มากนัก และยิ่งเราใช้ภาษาระดับสูง หน่วยความจำนี้จะใช้ในการประมวลผลสิ่งที่เรียกว่า นิพจน์ (Expression) เช่น (A+9)*2 อย่างนี้เรียกว่า นิพจน์ ... ซึ่งการทำงานนั้น ตัวแปลภาษาจะทำการแปลงนิพจน์ ให้อยู่ในรูปแบบที่ตัวเองประมวลผลได้ และเมื่อจัดรูปแบบได้แล้ว ก็จะใช้สแตกเป็นส่วนประมวลผล รายละเอียดขอไม่กล่าวมากกว่านี้นะครับ เพราะมันเป็นหัวเรื่องหนึ่งในรายวิชา อัลกอริธึม หรือไม่ก็วิชา โครงสร้างข้อมูล

 จุดประสงค์

            ศึกษารูปแบบของคำสั่งที่ใช้กับหน่วยความจำสแตก

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

        การกำหนดขนาดของสแตก

                เราสามารถกำหนดขนาดของแสตกด้วยการบอกจุดแรกของสแตก ผ่านทางเรจิสเตอร์ SP โดยสั่งว่า

                                 LDS       #0FFh

                 ซึ่งตัวอย่างนี้หมายความว่า เราให้ Stack ตัวบนสุดนั้นอยู่ที่ตำแหน่ง FFh หรือ 255 ดังนั้น พอเรา PUSH ค่าลงในแสตก ข้อมูลก็จะอยู่ที่ FFh แล้วตัวชี้ ก็จะลดค่าตัวเองลง 1 ค่า คือ ชี้ที่ตำแหน่ง FEh ถ้าเรายัง PUSH ลงไปอีก ข้อมูลตัวที่ 1 นี้จะอยู่ที่ตำแหน่ง FEhh ส่วนค่าตัวชี้ก็จะลดมากลายเป็น FDh แต่ถ้าเรา POP ข้อมูลออก ตัวชี้ก็จะเลื่อนขึ้นมา 1 ค่าเช่นกัน

         หมายเหตุ   

                ถ้าข้อมูลเป็นข้อมูลแบบ 16 บิต การเพิ่มลดนั้น จะเพิ่มลดครั้งละ 2 ไบต์

          คำสั่งสำหรับการ PUSH ได้แก่ PSHA, PSHB, PSHX, PSHY, TXS, และ TYS

                   

PSHA

รูปแบบ PSHA
ผลต่อ CCR ไม่มี
หน้าที่   นำค่าในเรจิสเตอร์ A ไปเก็บในสแตก แล้วลดค่าของตัวชี้ลง 1 ค่า
   

PSHB

รูปแบบ PSHB 
ผลต่อ CCR ไม่มี
หน้าที่   นำค่าในเรจิสเตอร์ B ไปเก็บในสแตก แล้วลดค่าของตัวชี้ลง 1 ค่า
   
PSHX
รูปแบบ PSHX
ผลต่อ CCR ไม่มี
หน้าที่   นำค่าในเรจิสเตอร์ IX ไปเก็บในสแตก แล้วลดค่าของตัวชี้ลง 2 ค่า             
   

PSHY

รูปแบบ PSHY
ผลต่อ CCR ไม่มี
หน้าที่   นำค่าในเรจิสเตอร์ IY ไปเก็บในสแตก แล้วลดค่าของตัวชี้ลง 2 ค่า
   
TXS
รูปแบบ TXS
ผลต่อ CCR ไม่มี
หน้าที่   นำค่าตัวชี้ (SP) บวกอีก 1 ค่า แล้วนำมาใส่ใน IX
   
TYS
รูปแบบ TYS
ผลต่อ CCR ไม่มี
หน้าที่   นำค่าตัวชี้ (SP) บวกอีก 1 ค่า แล้วนำมาใส่ใน IY
   

    

         คำสั่งสำหรับการ POP ได้แก่ PULA, PULB, PULX, PULY, TSX, และ TSY

     

PULA

รูปแบบ PULA
ผลต่อ CCR ไม่มี
หน้าที่   ดึงค่าชั้นบนสุดของ Stack มาไว้ในเรจิสเตอร์ A แล้วค่าของตัวชี้เพิ่มขึ้น 1 ค่า
   
PULB
รูปแบบ PULB
ผลต่อ CCR ไม่มี
หน้าที่   ดึงค่าชั้นบนสุดของ Stack มาไว้ในเรจิสเตอร์ B แล้วค่าของตัวชี้เพิ่มขึ้น 1 ค่า
   
PULX
รูปแบบ PULX
ผลต่อ CCR ไม่มี
หน้าที่   ดึงค่าชั้นบนสุดของ Stack มาไว้ในเรจิสเตอร์ IX แล้วค่าของตัวชี้เพิ่มขึ้น 2 ค่า
   

PULY

รูปแบบ PULY
ผลต่อ CCR ไม่มี
หน้าที่   ดึงค่าชั้นบนสุดของ Stack มาไว้ในเรจิสเตอร์ IY แล้วค่าของตัวชี้เพิ่มขึ้น 2 ค่า
   
TSX
รูปแบบ TSX
ผลต่อ CCR ไม่มี
หน้าที่   กำหนดให้ค่าของ SP เป็น IX - 1
   
TSY
รูปแบบ TSY
ผลต่อ CCR ไม่มี
หน้าที่   กำหนดให้ค่าของ SP เป็น IY - 1
   

      

   สรุป

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

  


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