สถาปัตยกรรมของ CPU 8086

โครงสร้างสถาปัตยกรรมของ CPU 8086 (8086 block diagram)
8086 มีแอดเดรส 20 เส้น ซึ่งทำให้อ้างแอดเดรสได้ถึง 1,045,576 ไบต์ (หรือ 1 เมกะไบต์) หรือมากเป็น 16 เท่า ของไมโครโปรเซสเซอร์ขนาด 8 บิต data bus มีขนาด 16 บิต ทำให้ 8086 สามารถเรียกข้อมูลได้ทีละ 1เวิร์ด หรือ 2 ไบต์ได้และยังเตรียมพร้อมสำหรับการทำงานแบบ ใช้หลาย CPU และรวมทั้งการทำงาน ร่วม กับอุปกรณ์อื่นที่จะทำงานร่วมกัน 8086 ได้ด้วย

รูปแสดง block diagram ของ CPU 8086

Register ของ CPU 8086

รีจิสเตอร์ของ 8086 ประกอบด้วยรีจิสเตอร์สำหรับจุดประสงค์ทั่วไป, รีจิสเตอร์ ชี้คำสั่ง flag และ เซกเมนต์ รีจิสเตอร์ รีจิสเตอร์เหล่านี้นำมาใช้งานสำหรับการอ้าง address แสดงสถานะของเครื่อง และสำหรับ fetch คำสั่งเพื่อมาตีความ และกระทำตาม
ในบรรดารีจิสเตอร์ที่มีอยู่ทั้งหมดของ 8086 เป็นรีจิสเตอร์ขนาด 16 บิต รีจิสเตอร์ AX จะประกอบ ด้วย AH และ AL โดย AX ทำหน้าที่ในการใช้คูณหารหรือเป็นรีจิสเตอร์ เกี่ยวกับอินพุตเอาต์พุต ที่เป็นเวิร์ด AL ทำ หน้าที่ใข้ในการคำนวณ คูณหาร หรือทำงานเกี่ยวกับอินพุต เอาต์พุท แปลง ข้อมูลจัดการคำนวณแบบตัวเลข ฐานสิบแบบ 8 บิต ส่วน AH ใช้เป็นรีจิสเตอร์ในการคูณและ หารได้ BX ใช้ในการแปลงข้อมูล CX ใช้ในคำสั่ง จัดการเกี่ยวกับสตริง และการลูป CL ใช้เป็นตัวแปรสำหรับการเลื่อนบิตหรือหมุนบิต DX ใช้ในคำสั่งคูณ หารเป็นเวิร์ดหรือใช้ในรูปแบบอ้างอินพุตเอาต์พุตแบบอ้อม SP ใช้กับคำสั่งสแตก SI และ DI ใช้กับคำสั่งที่เกี่ยวกับสตริง

รูปแสดงรีจิสเตอร์ที่ใช้ในไมโครโปรเซสเซอร์ 8086

รีจิสเตอร์ใช้งานทั่วไปของ 8086

รีจิสเตอร์ใน 8086 ประกอบด้วย รีจิสเตอร์ต้นทางหรือ source และ รีจิสเตอร์ ปลายทางหรือ destination BX(base) , SP (stack pointer), BP (base pointer), SI (source index) และ DI (destination index) ซึ่งสามารถที่จะนำมาเป็นตัวอ้าง address ได้ ดังรูป

รูปแสดงโครงสร้างรีจิสเตอร์ของ 8086 กับการคำนวณแอดเดรส

รีจิสเตอร์ขนาด 16 บิต ภ ตัวซึ่งได้แก่ AX (accumulator) , BX (base) , CX (counter) และ DX (data) ยังถูกแบ่งออกเป็นครึ่งบน (AH, BH, CH และDH) และครึ่งล่าง (AL, BL, CL และ DL) รีจิสเตอร์เหล่านี้อาจจะทำงานในลักษณะ  เป็นเวิร์ดหรือไบต์ก็ได้ ในกลุ่มนี้ถือว่าเป็นรีจิสเตอร์ ข้อมูล รีจิสเตอร์ในกลุ่ม pointer และ index มักจะนำ ไปใช้ในการอ้าง address และยังใช้ในการกระทำ ทางคณิต ศาสตร์และลอจิกได้
รีจิสเตอร์ BP และ SP มักจะใช้ในการชี้สแตก เพื่อจะทำการเก็บตำแหน่ง address กลับจาก โปรแกรมย่อย โดยใช้หลักการเหมือนสแตกของ CPU 8 บิต ส่วน BP นั้นจะใช้สำหรับเป็น ตัวบวก เพื่อชี้ค่าสแตกอีกทีหนึ่ง เพื่อจะเป็นวิธีที่จะอำนวยความสะดวกในการส่งค่า พารามิเตอร์เข้าสู่โปรแกรมโดยผ่านทาง สแตก ซึ่งช่วยใน การส่งค่าของตัวแปรระหว่างโปรแกรได้ดี รีจิสเตอร์ SI และDI จะทำการติดต่อกับหน่วยความจำได้ ซึ่งจะใช้งานได้ดีในกลุ่มคำสั่งพวก สตริงและการ ทำงานเป็น block หรือ การเชื่อมโยงข้อมูลในโครงสร้างแบบ array
ในการ fetch คำสั่งของ 8086 จะใช้ IP (instruction pointer) ขนาด 16 บิต เป็นตัวชี้ตำแหน่ง address ของ คำสั่งถัดไปที่จะถูกทำงาน ซึ่งความจริงแล้วค่าใน IP ไม่ได้กำหนดตำแหน่งโดยตรง แต่จะ มีการคำนวณมาก่อน
8086 เป็น flag สถานะจำนวน 6 บิต และ flag ควบคุมจำนวน 3 บิตซึ่งบรรจุอยู่ในรีจิสเตอร์ขนาด 16 บิต


รูปแสดง flag ของ 8086 ที่ใช้ในการทดสอบการทำงานของ CPU

flag ได้ถูกออกแบบมาเพื่อแสดงผลของการกระทำทางคณิตศาสตร์และลอจิกสถานะที่เป็น ไปได้ของ flag จะมีสองสถานะ คือ ถูก เซตทำให้มีค่าเป็น 1หรือถูกรีเซตให้มีค่าเป็น 0 แฟล็กตัวทด (carry flag) จะแสดง ลักษณะบอกการทดหรือ การขอยืมของบิตสูงสุดของผลลัพธ์ , แฟล็กพาริตี้ (parity flag) จะใช้แสดงจำนวนคู่หรือคี่ของตัวเลขที่เป็น 1 ในรีจิสเตอร์ ถ้าเป็นคู่ flag นี้จะถูกเซตเป็น 1, แฟล็กทดช่วย (auxiliary carry flag) จะใช้งานแบบ "decimal adjust", แฟล็กศูนย์ (zero flag) จะเป็น 1 เมื่อผลลัพธ์เป็นศูนย์ , แฟล็ก เครื่องหมาย (sign flag) จะได้รับ การเซตเมื่อผลลัพธ์เป็นเลขลบ , โอเวอร์โฟลว์แฟล็ก (OF) ใช้เพื่อแสดงว่ามีความผิดพลาด ในการคำนวณ เนื่องจากการใส่เครื่องหมายของผลลัพธ์ เช่น  ถ้ามีการบวกเลข +127 กับ +2 ผลลัพธ์ที่ได้ถ้าคิดคำนวณแบบมีเครื่องหมายจะได้คำตอบเป็น -127 ซึ่งผิดความหมาย ลักษณะ นี้จะเกิดการ โอเวอร์โฟลว์ให้แฟล็ก เป็น 1
แฟล็กควบคุมทิศทางของ 8086 (direction flag)จะกำหนดทิศทางของกลุ่มคำสั่งเกี่ยวกับสตริง ว่าจะมีทิศทาง การทำงานจากแอดเดรสมากไปน้อย หรือจากแอดเดรสน้อยไปมากนั่นเอง , แฟล็กอินเตอร์รัพท์ (IE) ถ้าได้ รับการเซตเป็น 1

แสดงว่าจะยอมรับอินเตอร์รัพท์จากภายนอก และ Tap flag (TF) จะทำให้ 8086 ทำงาน แบบทีละคำสั่งเพื่อการแก้ไขโปรแกรม

เซกเมนต์รีจิสเตอร์

มี 4 ตัว คือ CS(code segment) , DS(data segment) , SS(stack segment), ES(extra segment) ซึ่ง จะนำมาใช้ในหลักการแบบบล็อกแอดเดรสของ 8086 หน่วย ความจำได้รับการจัดสรรเป็นส่วนใหญ่ ๆ คือ code (หรือชุดคำสั่ง) ,ข้อมูล (ตัวเลข หรือตัวอักษร) และสแตกสำหรับการเก็บค่าแอดเดรสกลับคืนจากโปรแกรมย่อยเพื่อที่จะ ป้องกันการสับสน จึงกำหนดค่าให้ แยกกันได้
8086 จะมองลักษณะของหน่วยความจำ โดยแบ่งหน่วยความจำเป็นกลุ่ม ๆ ในรูปแบบของ เซกเมนต์ ในหนึ่ง เซกเมนต์จะชี้ได้ถึง 64 กิโลไบต์ เซกเมนต์ทั้งสี่ตัว จะแสดงแอดเดรสเริ่ม ต้นของหน่วยความจำที่จะติดต่อด้วย ดังรูป CS จะบรรจุค่าแสดงแอดเดรสเริ่มต้นของโปรแกรม DS จะเก็บค่า data segment ขณะนั้น SS จะ เก็บค่าสแตกเซกเมนต์ ขณะนั้นและ ES จะกำหนด segment ของข้อมูลรวมที่เรียกว่า global data segment

เซกเมนต์จะแสดงตำแน่งเหมือนกับ paragraph โดยจะเลื่อนไปทางซ้าย 4 บิต เพื่อที่จะกำหนด หรืออ้าง แอดเดรสให้ครบ 20 เส้น โดยจุดเริ่มต้นของ paragraph จะต้องมี 4 บิต หลังสุดเป็น 0 เช่น เป็น 00000H, 00010H , 00020H เป็นต้น
จากรูป ค่าของ SS จะชี้ตำแหน่งของเซกเมนต์ค่า D89F0 สังเกตเห็นว่าส่วนพื้นที่ ของหน่วย ความจำอาจจะ สลับหรือใช้บริเวณเดียวกันของหน่วยความจำได้

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

เช่นถ้าเซกเมนต์มีค่า E89F จะให้ออฟเซตมีค่า 0003H จะทำให้การอ้างแอดเดรสไปที่ 89F3
การจะใช้เซกเมนตฺรีจิสเตอร์และค่าออฟเซตตัวใดนั้นจะขึ้นอยู่กับชนิดของคำสั่งด้วย ดังแสดงในตาราง
      ชนิดของการอ้างหน่วยความจำ
      ค่าเซกเมนต์โดยปกติ
      ค่าเซกเมนต์ที่เลือกได้
      ค่าออฟเซต 
      การเฟตช์คำสั่ง
      CS
      -
      IP
      การทำสแตก
      SS
      -
      SP
      กำหนดตัวแปร
      DS
      CS,ES,SS
      ค่าแอดเดรสที่กำหนด
      สติรงต้นทาง
      DS
      CS,ES,SS
      SI
      สตริงปลายทาง
      ES
      -
      DI
      เบสรีจิสเตอร์ BP
      SS
      CS,ES,SS
      ค่าแอดเดรสที่กำหนด

การจัดขาของ 8086

8086 เป็นไมโครโปรเซสเซอร์ที่มีขาเพียง 40 ขาเท่านั้น โดยแบ่งเป็นขาแอดเดรสที่ multiplex ร่วมกับขาข้อมูล 16 ขา คือ AD0 - AD15และยังมีแอดเดรสเพิ่มขึ้นมา อีก 4 ขา คือ A16 - A19 ซึ่ง multiplex กับ S3 - S6 นอกจากนี้จะเป็นขา ที่เป็น สัญญาณควบคุมอื่น ๆ การจัดขาทั้งหมด แสดงดังรูป

เนื่องจาก 8086 มี บัสขนาด 16 บิต แต่ยังคงติดต่อกับข้อมูลในลักษณะเป็นไบต์ ดังนั้นในข้อมูล 16 บิต จึงแบ่งเป็นไบต์สูงและไบต์ต่ำ โครงสร้างการเชื่อมต่อกับหน่วยความจำจึงแยกด้วย /BHE หรือสัญญาณเลือกไบต์สูง
        ขา
        หน้าที่
        ชนิด
        AD0 - AD15 บัสแอดเดรสและข้อมูล 2 ทิศทางแบบลอจิกสามสถานะ
        A16/S3 - A17/S4 แอดเดรส/ตัวบอกเซกเมนต์ เอาต์พุตแบบลอจิกสามสถานะ
        A18/S5 แอดเดรส/ตัวอินเตอร์รัพท์อีนาเบิล เอาต์พุทแบบลอจิกสามสถานะ
        A19/S6 แอดเดรส/บิตแสดงสถานะ เอาต์พุตแบบลอจิกสามสถานะ
        /BHE/S7 บิตบอกข้อมูลไบต์บน/บิตแสดงสถานะ เอาต์พุตแบบลอจิกสามสถานะ
        RD บิตควบคุมการอ่าน เอาต์พุตแบบลอจิกสามสถานะ
        READY บิตควบคุมจังหวะการ Wait อินพุต
        /TEST บิตบอกการรอคอยสำหรับการทดสอบ อินพุต
        INTR อินเตอร์รัพท์ อินพุต
        NMI นอนมาสเคเบิลอินเตอร์รัพท์ อินพุต
        RESET รีเซต อินพุต
        CLK สัญญาณนาฬิกา อินพุต
        MN/MX ถ้าเป็น 0 หมายถึงระบบเป็นชนิด 

        maximum system

        S0S1S2 บอกสถานะ machine cycle เอาต์พุตแบบลอจิกสามสถานะ
        /RQ/GTO,/RQ/GTI บิตควบคุมลำดับสำคัญของบัส สองทิศทาง
        GSO,QSI บิตแสดงคิวของคำสั่ง เอาต์พุต
        /LOCK บัสควบคุม hold เอาต์พุตแบบลอจิกสามสถานะ
        M/IO เลือกหน่วยความจำหรืออินพุตเอาต์พุต เอาต์พุตแบบลอจิกสามสถานะ
        /WR เขียน เอาต์พุตแบบลอจิกสามสถานะ
        /ALE แลทช์แอดเดรส เอาต์พุต
        DT/R รับส่งข้อมูล เอาต์พุตแบบลอจิกสามสถานะ
        /DEN การอีนาเบิ้ลข้อมูล เอาต์พุตแบบลอจิกสามสถานะ
        /INTA  ตอบรับอินเตอร์รัพท์ เอาต์พุต
        HOLD บอกการ hold อินพุต
        HOLDA ตอบรับการ hold เอาต์พุต
        Vcc GND แหล่งจ่ายไฟ ground

อินเตอร์รัพท์ของ 8086

อินเตอร์รัพท์ของ 8086 สามารถจะมจากหลาย ๆ แหล่งได้อินเตอร์รัพท์อาจจะ มาจาก อุปกรณ์ ภายนอก มาโดยทาง software หรือมาจากตัว 8086 เองก็ได้ อินเตอร์รัพท์จากอุปกรณ์ภายนอก เข้ามาทางขา 2 ขา คือ INTR(interrupt

request) และ NMI(non-maskable interrupt) โดยที่ INTR จะถูกกำหนดให้ทำงานได้โดยคำสั่ง IE(interrupt enable flag) ที่เป็นส่วนหนึ่งของ 8086 flag ถ้า flag IE ถูกเซตจะ ทำให้ 8086 สามารถจะรับอินเตอร์รัพท์จาก INTR ได้ แต่ถ้า
IF ถูกเคลียร์ 8086 จะ ไม่รับอินเตอร์รัพท์จาก INTR ส่วน NMI จะเป็นอินเตอร์รัพท์ที่ไม่สามารถจะหยุดได้ มักจะ ใช้ในกรณีที่เกิดเหตุการณ์สำคัญเช่นเกิดความผิดพลาดของพาริตี้ของ หน่วยความจำ (memory parity) หรือเกิดไฟตก เป็นต้น
INTO (interrupt overflow) คือ อินเตอร์รัพท์ของ 8086 ที่เกิดจากข้อผิดพลาดของการหารและ การทำงานทีละขั้น ข้อผิดพลาดจากการหาร (divide error) เกิดขึ้นเนื่องจากผลของการหารอาจจะมีค่ามากกว่าเนื้อที่ที่เตรียมไว้เป็นที่เก็บ

ผลลัพธ์ หรืออาจจะเกิดจากการหารด้วยเลข 0 หรืออาจจะเกิดการหารด้วยเลข 1 หรือด้วย เลขมาก ๆ ส่วนลักษณะของการทำงานทีละขั้น (single step) จะเป็นอินเตอร์รัพท์ ที่เกิดเนื่องจาก execute คำสั่งทีละคำสั่งเหตุการณ์นี้เกิดขึ้นเนื่องจาก TF (trap flag) ในรีจิสเตอร์แฟล็กถูกเซตให้เป็น 1
เมื่อเกิดอินเตอร์รัพท์เหล่านี้ขึ้นมาแล้วก็จะเกิดเหตุการณ์เฉพาะอย่างขึ้นถ้ามีการอินเตอร์รัพท์ จากภายนอก คำสั่งชุดสุดท้ายจะถูก execute จนเสร็จสิ้นก่อน (ยกเว้น ถ้าเป็นคำสั่ง MOV หรือ POP จะมีการ execute คำสั่งต่อไปก่อน

แล้วจึงหยุด) อินเตอร์รัพท์ทุกตัวจะทำการ เก็บค่า ของแฟล็กรีจิสเตอร์ไว้ในสแตก เสร็จแล้ว 8086 จะทำการรีเซตแฟล็ก IF และ TF ให้เป็น 0 ทั้งนี้เพื่อป้องกัน INTR อินพุตที่เข้ามาใหม่ และป้องกันการเกิดการทำงานทีละขั้นในขณะที่อยู่ใน
โปรแกรมอินเตอร์รัพท์ เนื่องจากการที่แฟล็กถูกเก็บค่าไว้หลังจากโปรแกรมอินเตอร์รัพท์ สิ้นสุดแล้วค่าต่าง ๆ ที่เก็บไว้จะถูกดึงกลับมาใช้งานได้ จากนั้น 8086 จะทำการเก็บค่าของ CS และ IP ลงบนสแตกเพื่อที่จะเก็บตำแหน่ง
ของแอดเดรสที่ส่งกลับ (return address) ในลักษณะเดียว กับคำสั่ง far CALL และในขั้นตอนสุดท้าย CS และ IP จะถูกอ่านจาก ตารางของ interrupt vector (ขึ้นกับหมายเลขอินเตอร์รัพท์) ตารางของ interrupt vector ก็คือบริวเณของ
เนื้อที่ของหน่วย ความจำเริ่มตั้งแต่แอดเดรส 0000 จำนวน หนึ่งกิโลไบต์ดังแสดงในรูป

อินเตอร์รัพท์แต่ละตัวจะชี้ไปยังตำแหน่งที่แน่นอน และสามารถที่จะกระโดด ไปถึงที่กำหนด ได้โดยอัตโนมัติ เมื่อเกิดอินเตอร์รัพท์จากลักษณะของ divide error จะทำให้ เกิดอินเตอร์รัพท์ 0, single-step จะเป็นอินเตอร์รัพท์ 1,

อินเตอร์รัพท์แบบ non- maskable เป็นแบบอินเตอร์รัพท์ 2 , bread-oint จะเกิดอินเตอร์รัพท์ 3 , และการ เกิด over flow จะเป็นอินเตอร์รัพท์ 4 ส่วน อินเตอร์ รัพท์ 5 ถึง 31 เตรียมไว้สำหรับ ผู้ใช้จะกำหนดเอาเองภายหลัง ส่วนอินเตอร์รัพท์ที่เหลือเราอาจ จะควบคุมโดยใช้ คำสั่ง INTR หรือ INT ได้
สำหรับ INTR จะตอบรับสัญญาณอินเตอร์รัพท์จากภายนอก แต่ส่วน INT จะรับได้โดยตัวคำสั่ง นั่นเอง 8086 สามารถที่จะรับรู้ชนิดของการอินเตอร์รัพท์ได้โดยการ คูณด้วย 4 ที่ค่าของคำสั่ง ผลลัพธ์ที่ได้จะบอกตำแหน่งที่ของตาราง

อินเตอร์รัพท์ ซึ่งค่าของตารางจะถูกส่งค่าไปยัง CS และ IP ค่าต่าง ๆในตาราง เราจะต้องเป็นผู้ กำหนดโดยกำหนดเป็นค่าของเซกเมนต์และค่าของออฟ เซต ที่แสดงตำแหน่งของ อินเตอร์รัพท์รูทีน ยกตัวอย่างเช่น อินเตอร์รัพท์ที่แอดเดรส 0 ถึง 3 เราจะต้องกำ หนดเป็นค่าบอกแอดเดรส CS และ IP เพื่อจะชี้รูทีนของ divide error เป็นต้น
อินเตอร์รัพท์รูทีน จะต้องเริ่มต้นด้วยการเก็บค่าของรีจิสเตอร์ต่าง ๆไว้ก่อน เพราะ เราไม่ทราบว่า จะเกิดอินเตอร์รัพท์เมื่อถึงจุดใด และเราไม่ต้องการทำให้ค่า รีจิสเตอร์ ต่าง ๆ เสียไปและเราต้อง ปิดท้ายรูทีนด้วยคำสั่ง IRET คำสั่งนี้จะทำงานเหมือน คำสั่ง RET ธรรมดาแต่จะทำการอ่านค่าของแฟล็กออกมา จากสแตกด้วย
คำสั่ง INT สามารถตรวจสอบว่าจะไปที่ตำแหน่งใดได้โดยต้องกำหนดด้วยหมายเลข แสดงอิน เตอร์รัพท์ ทำให้การเรียกใช้งานเป็นไปได้โดยง่ายและสะดวก
คำสั่ง INTO เป็นอินเตอร์รัพท์ที่ตรวจสอบเงื่อนไขแฟล็ก over flow นั่นคือจะเกิดการอินเตอร์รัพท์ หมายเลข 4 เมื่อแฟล็ก OF เป็น 1 แต่ถ้าแฟล็กนี้เป็น 0 จะไม่มี อินเตอร์รัพท์แต่จะ execute คำสั่ง ถัดไป
มีคำสั่งพิเศษ 2 คำสั่งที่ช่วยในการตรวจสอบโปรแกรม นั่นคือ คำสั่ง INT 3 เราจะทำการแทน คำสั่งนี้ไปยังตำแหน่งคำสั่งที่บอกจุดหยุด เมื่อมีการ execute มาถึงคำสั่งดังกล่าวอินเตอร์รัพท์ รูทีนอาจจะทำการเก็บค่ารีจิสเตอร์ต่าง ๆ ลงในสแตกหรือไว้ในตำแหน่งหน่วยความจำที่ กำหนดได้
อีกวิธีหนึ่งในการตรวจสอบ (debug) โปรแกรม อาจทำได้โดยการเซตแฟล็กแทร็ป (trap flag) ไว้ เมื่อแฟล็กแทร็ปเป็น 1 แล้ว 8086 จะจัดการทำให้เกิด INT 1 (single-setp) ขึ้นต่อทุกคำสั่งยกเว้น คำสั่ง MOV หรือ POP ที่ติดต่อกับรีจิสเตอร์ เซกเมนต์


รวบรวมจาก บทเรียน Online วิชา 204323 ไมโครโปรเซสเซอร์และการออกแบบไมโครคอมพิวเตอร์ รศ.ยืน ภู่วรวรรณ