[ บทความ : มาเขียนโปรแกรมกับ 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 |
สรุป
ตอนนี้เราได้เรียนรู้คำสั่งเกี่ยวกับสแตกเรียบร้อยแล้วครับ
คราวหน้าจะเป็นคำสั่งที่เกี่ยวกับการหมุนและเลื่อนบิต
ครับ ...