ความเป็นจริงที่น่ารังเกียจ # 2 :
ค่าใช้จ่าย . แม้ว่ามันจะเป็นไปได้ที่จะใช้นับล้านทรานซิสเตอร์บน CPU วันนี้, ทรานซิสเตอร์ยิ่งคุณใช้มีราคาแพงกว่าซีพียู โปรเซสเซอร์ Pentium IV ตัวอย่างเช่นหลายร้อยดอลลาร์ค่าใช้จ่าย (ประมาณ 2002) CPU ที่มีเพียง 30,000 ทรานซิสเตอร์ (หรือราว 2002) จะเสียค่าใช้จ่ายเพียงไม่กี่ดอลลาร์ สำหรับระบบที่ใช้ต้นทุนต่ำก็อาจจะมีความสำคัญมากขึ้นที่จะโกนคุณสมบัติบางอย่างและใช้ทรานซิสเตอร์น้อยลงจึงลดค่าใช้จ่ายของ CPU
ความเป็นจริงที่น่ารังเกียจ # 3 :
ขยาย .
หนึ่งปัญหากับวิธีการ "ครัวอ่างล้างจาน" เป็นว่ามันเป็นเรื่องยากมากที่จะคาดหวังคุณลักษณะทั้งหมดที่คนจะต้องการ ตัวอย่างเช่น MMX และการปรับปรุงการเรียนการสอน SIMD ของอินเทลได้เพิ่มขึ้นจะทำให้การเขียนโปรแกรมมัลติมีเดียปฏิบัติเพิ่มเติมเกี่ยวกับการประมวลผลเพนเทียม กลับในปี 1978 คนน้อยมากที่จะได้อาจจะเป็นที่คาดว่าจะต้องใช้คำแนะนำเหล่านี้
ความเป็นจริงที่น่ารังเกียจ # 4 :
มรดกสนับสนุน . นี้เกือบจะตรงข้ามของการขยาย มักจะเป็นกรณีที่มีการเรียนการสอนการออกแบบซีพียูรู้สึกเป็นสิ่งสำคัญที่จะออกมาจะมีประโยชน์น้อยกว่าที่คาดการณ์ไว้ ยกตัวอย่างเช่นการเรียนการสอน LOOP ใน 80x86 CPU เห็นการใช้งานน้อยมากในโปรแกรมที่มีประสิทธิภาพสูงที่ทันสมัย 80x86 ENTER การเรียนการสอนเป็นอีกหนึ่งตัวอย่างที่ดี เมื่อมีการออกแบบซีพียูใช้วิธี "ครัวอ่างล้างจาน" ก็มักจะพบบ่อยในการค้นพบว่าโปรแกรมแทบไม่เคยใช้บางส่วนของคำแนะนำที่มีอยู่ แต่น่าเสียดายที่คุณไม่สามารถลบคำแนะนำในรุ่นที่ใหม่กว่าในการประมวลผลเพราะจะทำลายโปรแกรมที่มีอยู่บางส่วนที่ใช้คำแนะนำเหล่านั้น โดยทั่วไปเมื่อคุณเพิ่มการเรียนการสอนที่คุณต้องสนับสนุนมันตลอดไปในชุดคำสั่ง เว้นแต่โปรแกรมน้อยมากใช้การเรียนการสอน (และคุณยินดีที่จะปล่อยให้พวกเขาทำลาย) หรือคุณจะสามารถจำลองการเรียนการสอนในซอฟต์แวร์ที่ลบคำแนะนำเป็นสิ่งที่ยากมากที่จะทำ
ความเป็นจริงที่น่ารังเกียจ # 4 :
ความซับซ้อนของความนิยมของโปรเซสเซอร์ใหม่เป็นวัดได้ง่ายโดยวิธีการที่ซอฟต์แวร์มากคนเขียนสำหรับการประมวลผลที่ ส่วนใหญ่การออกแบบซีพียูตายตายอย่างรวดเร็วเพราะไม่มีใครเขียนซอฟแวร์ที่เฉพาะเจาะจงกับ CPU ที่ ดังนั้นนักออกแบบซีพียูจะต้องพิจารณาประกอบโปรแกรมเมอร์และนักเขียนคอมไพเลอร์ที่จะใช้ชิปที่แนะนำ ในขณะที่ "ครัวอ่างล้างจาน" วิธีการอาจดูเหมือนจะดึงดูดความสนใจการเขียนโปรแกรมดังกล่าวความจริงก็คือไม่มีใครต้องการที่จะเรียนรู้ระบบที่ซับซ้อนมากเกินไป ถ้า CPU ของคุณทำทุกอย่างภายใต้ดวงอาทิตย์นี้อาจดึงดูดคนที่มีความคุ้นเคยกับซีพียู แต่น่าเสียดายจิตวิญญาณที่ไม่ดีที่ไม่ทราบชิปและมีการเรียนรู้มันทั้งหมดในครั้งเดียว
ปัญหาเหล่านี้ด้วยวิธีการ "ครัวอ่างล้างจาน" ทุกคนมีวิธีการแก้ปัญหาร่วมกันออกแบบการเรียนการสอนที่ง่ายตั้งค่าให้เริ่มต้นด้วยและออกจากห้องพักสำหรับการขยายตัวในภายหลัง นี้เป็นหนึ่งในเหตุผลสำคัญที่ทำให้ 80x86 ได้พิสูจน์ให้เป็นที่นิยมและจีรัง อินเทลเริ่มต้นด้วย CPU ที่ค่อนข้างง่ายและคิดออกว่าจะขยายชุดการเรียนการสอนในช่วงหลายปีเพื่อรองรับคุณสมบัติใหม่
3 พื้นฐานการออกแบบการเรียนการสอนเป้าหมาย
ในแบบฉบับฟอนนอยมันน์ซีพียูสถาปัตยกรรมคอมพิวเตอร์เข้ารหัสคำแนะนำ CPU เป็นค่าตัวเลขและเก็บค่าตัวเลขเหล่านี้ในหน่วยความจำ การเข้ารหัสของคำแนะนำเหล่านี้เป็นหนึ่งในงานที่สำคัญในการออกแบบชุดคำสั่งและต้องใช้ความคิดระวังให้มาก
การเข้ารหัสการเรียนการสอนที่เราต้องเลือกค่า opcode ที่เป็นตัวเลขไม่ซ้ำกันสำหรับแต่ละคำสั่ง (เห็นได้ชัดว่าทั้งสองคำแนะนำที่แตกต่างกันไม่สามารถใช้ค่าตัวเลขเดียวกันหรือ CPU จะไม่สามารถที่จะแยกความแตกต่างของพวกเขาเมื่อมันพยายามที่จะถอดรหัสค่า opcode) มีจำนวน n บิตมี 2
nopcodes เป็นไปได้ที่แตกต่างกันเพื่อให้คำแนะนำการเข้ารหัสเมตรคุณจะต้อง opcode ที่อย่างน้อยเข้าสู่ระบบ
2 (เมตร) บิตนาน
การเข้ารหัส opcodes เป็นเพียงเล็กน้อยที่เกี่ยวข้องมากขึ้นกว่าการกำหนดค่าตัวเลขที่ไม่ซ้ำกันแต่ละคำสั่ง โปรดจำไว้ว่าเราจะต้องใช้ฮาร์ดแวร์ที่เกิดขึ้นจริง (เช่นวงจรถอดรหัส) จะคิดออกว่าแต่ละคำสั่งและคำสั่งไม่ส่วนที่เหลือของฮาร์ดแวร์ที่จะทำงานที่ระบุ สมมติว่าคุณมี opcode เจ็ดบิต กับ opcode ขนาดนี้เราสามารถเข้ารหัส 128 คำแนะนำที่แตกต่างกัน เพื่อถอดรหัสแต่ละคำสั่งเป็นรายบุคคลต้องเจ็ดเส้น 128 เส้นถอดรหัส - ชิ้นราคาแพงของวงจรสมมติว่าคำแนะนำของเรามีรูปแบบบางอย่างเราสามารถลดฮาร์ดแวร์ถอดรหัสโดยการเปลี่ยนขนาดใหญ่นี้มีสามตัวถอดรหัสขนาดเล็ก
หากคุณมี 128 คำแนะนำซ้ำกันอย่างแท้จริงมีเพียงเล็กน้อยที่คุณสามารถทำได้นอกเหนือจากการถอดรหัสแต่ละคำสั่งเป็นรายบุคคล อย่างไรก็ตามในสถาปัตยกรรมมากที่สุดคำแนะนำไม่ได้เป็นอิสระจากอีกคนหนึ่ง ยกตัวอย่างเช่นซีพียู 80x86 opcodes สำหรับ "MOV (EAX, ebx);" และ "MOV (ECX, EDX);" มีความแตกต่างกัน (เพราะเหล่านี้มีคำแนะนำที่แตกต่างกัน) แต่คำแนะนำเหล่านี้จะไม่เป็นที่ไม่เกี่ยวข้องกัน พวกเขาทั้งสองย้ายข้อมูลจากที่หนึ่งไปยังอีกที่ลงทะเบียน ในความเป็นจริงที่แตกต่างระหว่างพวกเขาเป็นแหล่งที่มาและปลายทางตัวถูกดำเนินการ นี้แสดงให้เห็นว่าเราสามารถเข้ารหัสคำแนะนำเช่น MOV กับย่อย opcode และการเข้ารหัสตัวถูกดำเนินการโดยใช้สายอื่น ๆ ของบิตใน opcode
ตัวอย่างเช่นถ้าเราจริงๆมีเพียงแปดคำแนะนำแต่ละคำสั่งมีสองตัวถูกดำเนินการและแต่ละตัวถูกดำเนินการสามารถเป็นหนึ่งในสี่ค่าที่แตกต่างกันแล้วเราสามารถเข้ารหัส opcode เป็นสาขาเต็มไปสามมีสามสองและสองบิต (ดู
รูปที่ 5.1 ) การเข้ารหัสนี้จะต้องใช้สามถอดรหัสง่ายที่สมบูรณ์ตรวจสอบสิ่งที่การเรียนการสอนของ CPU ควรดำเนินการ
ขณะนี้เป็นบิตของกรณีที่เล็กน้อยก็ไม่แสดงให้เห็นถึงแง่มุมหนึ่งที่สำคัญมากของการออกแบบชุดคำสั่ง - มันเป็นสิ่งสำคัญที่จะทำให้ opcodes ง่ายต่อการถอดรหัสและวิธีที่ง่ายที่สุดที่จะทำนี้คือการเลิก opcode ในหลายสาขาที่แตกต่างกันบิต, ข้อมูลส่วนแต่ละส่วนของข้อมูลที่จำเป็นในการดำเนินการเรียนการสอนเต็มรูปแบบ สาขาขนาดเล็กบิตเหล่านี้ได้ง่ายขึ้นมันก็จะเป็นฮาร์ดแวร์ที่จะถอดรหัสและดำเนินการได้
2 .
รูปที่ 1 การแยก Opcode เป็นเฉพาะกิจฟิลด์เพื่อความสะดวกในการถอดรหัส
แม้ว่าอินเทลอาจจะไปน้อยลงน้ำกับการออกแบบของเดิม 8086 ชุดคำสั่งเป้าหมายของการออกแบบที่สำคัญคือเพื่อให้การเรียนการสอนที่มีขนาดอยู่ในช่วงที่เหมาะสม ซีพียูที่มีคำแนะนำยาวโดยไม่จำเป็นใช้หน่วยความจำเพิ่มเติมสำหรับโปรแกรมของพวกเขา นี้มีแนวโน้มที่จะสร้างขึ้นแคชและดังนั้นเจ็บประสิทธิภาพโดยรวมของซีพียู ดังนั้นเราจึงต้องการคำแนะนำของเราจะเป็นขนาดเล็กที่สุดเท่าที่ทำได้เพื่อให้รหัสโปรแกรมของเราใช้หน่วยความจำน้อยที่สุดเท่าที่เป็นไปได้
มันจะดูเหมือนว่าถ้าเรามีการเข้ารหัส 2
nคำแนะนำที่แตกต่างกันโดยใช้บิต n จะมีงานที่คั่งค้างน้อยมากในการเลือกขนาดของการเรียนการสอน มันจะใช้เวลาบิต n การเข้ารหัสที่ 2
nคำแนะนำที่คุณไม่สามารถทำมันได้กับใด ๆ น้อยลง คุณอาจจะแน่นอนใช้มากกว่าบิต n; และเชื่อหรือไม่ว่าเป็นความลับในการลดขนาดของโปรแกรมทั่วไปบน CPU
ก่อนที่จะคุยถึงวิธีการใช้คำสั่งอีกต่อไปในการสร้างโปรแกรมที่สั้นกว่าการพูดนอกเรื่องสั้นเป็นสิ่งที่จำเป็น สิ่งแรกที่ควรทราบก็คือเรามักไม่สามารถเลือกหมายเลขของพลบิตสำหรับความยาว opcode ของเรา สมมติว่าซีพียูของเรามีความสามารถในการอ่านไบต์จากหน่วยความจำ opcode อาจจะต้องมีบางหลายแม้แปดบิตนาน ถ้า CPU ไม่สามารถอ่านไบต์จากหน่วยความจำ (เช่นส่วนใหญ่ RISC ซีพียูเพียงอ่านหน่วยความจำใน 32 หรือ 64 ชิ้นบิต) แล้ว opcode เป็นไปได้ขนาดเดียวกับวัตถุที่มีขนาดเล็กที่สุดของ CPU สามารถอ่านจากหน่วยความจำในครั้งเดียว (เช่น 32 บิตบนชิป RISC ทั่วไป) ความพยายามที่จะหดตัวขนาด opcode ด้านล่างบัสข้อมูลนี้บังคับใช้วงเงินที่ต่ำกว่าใด ๆ ที่เป็นประโยชน์ เนื่องจากเรากำลังพูดถึงสถาปัตยกรรม 80x86 ในข้อความนี้เราจะทำงานร่วมกับ opcodes ว่าต้องหลายแม้แปดบิตนาน
จุดที่จะต้องพิจารณาที่นี่ก็คือขนาดของตัวถูกดำเนินการเรียนการสอนของ นักออกแบบบาง CPU (โดยเฉพาะนักออกแบบ RISC) รวมถึงตัวถูกดำเนินการทั้งหมดใน opcode ของพวกเขา นักออกแบบ CPU อื่น ๆ (นักออกแบบมัก CISC) ไม่นับตัวถูกดำเนินการเช่นค่าคงที่ทันทีหรือการเคลื่อนอยู่เป็นส่วนหนึ่งของ opcode (แม้ว่าพวกเขาจะมักจะนับลงทะเบียนการเข้ารหัสตัวถูกดำเนินการเป็นส่วนหนึ่งของ opcode) เราจะใช้วิธีการ CISC ที่นี่และไม่นับอย่างต่อเนื่องทันทีหรืออยู่ที่ค่าการเคลื่อนที่เป็นส่วนหนึ่งของ opcode ที่เกิดขึ้นจริง
กับ opcode แปดบิตคุณจะสามารถเข้ารหัส 256 คำแนะนำที่แตกต่างกัน แม้ว่าเราจะไม่นับตัวถูกดำเนินการเรียนการสอนในฐานะที่เป็นส่วนหนึ่งของ opcode มีเพียง 256 คำแนะนำที่แตกต่างกันค่อนข้าง จำกัด มันไม่ใช่ว่าคุณไม่สามารถสร้าง CPU ที่ opcode แปดบิตส่วนใหญ่ของโปรเซสเซอร์แปดบิต predating 8086 มี opcodes แปดบิตก็เพียงว่าโปรเซสเซอร์ที่ทันสมัยมักจะมีมากกว่า 256 คำแนะนำที่แตกต่างกัน ขั้นตอนต่อไปก็คือการ opcode สองไบต์ กับ opcode สองไบต์เราสามารถมีได้ถึง 65,536 คำแนะนำที่แตกต่างกัน (ซึ่งอาจจะเป็นพอ) แต่คำแนะนำของเรามีสองเท่าในขนาด (ไม่นับตัวถูกดำเนินการของหลักสูตร)
ถ้าลดขนาดการเรียนการสอนเป็นเป้าหมายการออกแบบที่สำคัญ
3เราสามารถใช้เทคนิคบางอย่างจากทฤษฎีการบีบอัดข้อมูลเพื่อลดขนาดเฉลี่ยของคำแนะนำของเรา แนวคิดพื้นฐานคือ: ครั้งแรกที่เราวิเคราะห์โปรแกรมที่เขียนขึ้นสำหรับ CPU ของเรา (หรือ CPU คล้ายกับของเราถ้าไม่มีใครได้เขียนโปรแกรมใด ๆ สำหรับ CPU ของเรา) และนับจำนวนของการเกิดขึ้นของแต่ละ opcode ในจำนวนมากการใช้งานทั่วไป แล้วเราจะสร้างรายการที่จัดเรียงของ opcodes เหล่านี้ออกจากส่วนใหญ่ที่ใช้บ่อยในการน้อยที่สุดที่ใช้บ่อย จากนั้นเราก็พยายามที่จะออกแบบชุดคำสั่งของเราโดยใช้ opcodes หนึ่งไบต์สำหรับคำแนะนำมากที่สุดที่ใช้บ่อย, opcodes ไบต์สำหรับชุดต่อไปของคำแนะนำส่วนใหญ่ที่ใช้บ่อยและสาม (หรือมากกว่า) opcodes ไบต์สำหรับที่ไม่ค่อยได้ใช้ คำแนะนำ แม้ว่าขนาดการเรียนการสอนสูงสุดของเราอยู่ในขณะนี้สามหรือมากกว่าไบต์มากที่สุดของคำสั่งที่เกิดขึ้นจริงที่ปรากฏในโปรแกรมจะใช้หนึ่งหรือสอง opcodes ไบต์ดังนั้นความยาว opcode เฉลี่ยจะอยู่ที่ไหนสักแห่งระหว่างหนึ่งและสองไบต์ (ขอเรียกว่า 1.5 bytes) และ โปรแกรมทั่วไปจะสั้นลงกว่าที่เราเลือก opcode สองไบต์สำหรับคำแนะนำทั้งหมด (ดู
รูปที่ 5.2 )
|
รูปที่ 2 การใช้คำแนะนำในการเข้ารหัสตัวแปรความยาว Opcode
แม้ว่าจะใช้คำแนะนำยาวตัวแปรช่วยให้เราสามารถสร้างโปรแกรมขนาดเล็กก็มาในราคา แรกของทุกการถอดรหัสคำแนะนำมีความซับซ้อนมากขึ้นอีกนิดก่อนที่จะถอดรหัสข้อมูลการเรียนการสอนซีพียูต้องถอดรหัสขนาดการเรียนการสอนของ นี้ขั้นตอนพิเศษสิ้นเปลืองเวลาและอาจมีผลต่อประสิทธิภาพโดยรวมของ CPU (โดยการแนะนำความล่าช้าในขั้นตอนการถอดรหัสและจึง จำกัด ความถี่สัญญาณนาฬิกาสูงสุดของ CPU) มีปัญหากับคำแนะนำยาวตัวแปรก็คือว่ามันทำให้การถอดรหัสคำแนะนำหลายในท่อค่อนข้างยาก (เนื่องจากเราไม่สามารถตรวจสอบนิดขอบเขตการเรียนการสอนในคิว prefetch) ด้วยเหตุผลเหล่านี้พร้อมกับคนอื่น ๆ คือเหตุผลที่สถาปัตยกรรม RISC ที่นิยมมากที่สุดคำแนะนำหลีกเลี่ยงการปรับขนาด แต่สำหรับจุดประสงค์ของเราเราจะไปด้วยวิธีการระยะเวลาตัวแปรตั้งแต่ประหยัดหน่วยความจำเป็นเป้าหมายที่น่าชื่นชม
ก่อนที่จริงการเลือกคำแนะนำที่คุณต้องการที่จะใช้ในการทำงานของคุณตอนนี้จะเป็นช่วงเวลาที่ดีในการวางแผนสำหรับอนาคต ไม่ต้องสงสัยคุณจะค้นพบความจำเป็นในการคำสั่งใหม่ที่บางจุดในอนาคตดังนั้นการสำรอง opcodes บางส่วนเฉพาะสำหรับวัตถุประสงค์ที่เป็นความคิดที่ดีจริง ถ้าคุณได้รับการเรียนการสอนโดยใช้การเข้ารหัสที่ปรากฏใน
ภาพที่ 5.2สำหรับรูปแบบ opcode ของคุณก็อาจจะไม่ได้เป็นความคิดที่ดีที่จะสำรองหนึ่งช่วงตึกจาก 64 opcodes หนึ่งไบต์ครึ่ง (4,096) ของคำแนะนำสองไบต์และครึ่งหนึ่ง (1,048,576) ของ opcodes สามไบต์สำหรับใช้ในอนาคต โดยเฉพาะอย่างยิ่งให้ขึ้น 64 ของที่มีค่ามาก opcodes หนึ่งไบต์อาจดูเหมือนฟุ่มเฟือย แต่ประวัติศาสตร์แสดงให้เห็นว่าการคาดการณ์ดังกล่าวเป็นรางวัล
ขั้นตอนต่อไปคือการเลือกคำแนะนำที่คุณต้องการที่จะดำเนินการ ทราบว่าแม้ว่าเราได้ลิขสิทธิ์เกือบครึ่งหนึ่งคำแนะนำสำหรับการขยายตัวในอนาคตเราจะไม่จริงต้องดำเนินการตามคำแนะนำสำหรับทุก opcodes ที่เหลือ เราสามารถเลือกที่จะออกจากหมายเลขที่ดีของคำแนะนำเหล่านี้ unimplemented (และมีประสิทธิภาพสำรองพวกเขาในอนาคตได้เป็นอย่างดี) วิธีการที่เหมาะสมไม่ได้ที่จะเห็นวิธีการอย่างรวดเร็วเราสามารถใช้ขึ้น opcodes ทั้งหมด แต่เพื่อให้แน่ใจว่าเรามีชุดคำสั่งที่สอดคล้องกันและมีความสมบูรณ์ได้รับการประนีประนอมที่เราต้องอยู่กับ (เช่นข้อ จำกัด ของซิลิกอน) จุดหลักที่จะเก็บไว้ในใจที่นี่ก็คือว่ามันง่ายมากที่จะเพิ่มการเรียนการสอนต่อไปกว่านั้นคือการเอาการเรียนการสอนในภายหลัง ดังนั้นสำหรับครั้งแรกที่ไปรอบก็มักจะดีกว่าที่จะไปกับการออกแบบที่เรียบง่ายมากกว่าการออกแบบที่ซับซ้อนมากขึ้น
ขั้นตอนแรกคือการเลือกบางชนิดการเรียนการสอนทั่วไป สำหรับความพยายามครั้งแรกคุณควร จำกัด คำแนะนำเพื่อคำแนะนำที่รู้จักกันดีและบางอย่างร่วมกัน สถานที่ที่ดีที่สุดที่จะช่วยหาในการเลือกคำแนะนำเหล่านี้เป็นชุดคำสั่งในการประมวลผลอื่น ๆ ตัวอย่างเช่นการประมวลผลมากที่สุดที่คุณพบจะมีคำแนะนำดังต่อไปนี้:
คำแนะนำข้อมูลการเคลื่อนไหว (เช่น MOV)
คณิตศาสตร์และตรรกะคำแนะนำ (เช่น ADD, SUB, AND, OR, NOT)
ชุดของคำสั่งกระโดดเงื่อนไข (ใช้โดยทั่วไปหลังจากที่คำแนะนำเปรียบเทียบ)
เป้าหมายของคุณเป็นนักออกแบบของชุดคำสั่งของ CPU เริ่มต้นคือการเลือกชุดที่เหมาะสมของคำแนะนำที่จะช่วยให้โปรแกรมเมอร์ที่จะเขียนได้อย่างมีประสิทธิภาพโปรแกรม (ใช้คำแนะนำไม่กี่เท่าที่เป็นไปได้) โดยไม่ต้องเพิ่มคำแนะนำเป็นจำนวนมากเพื่อให้คุณเกินงบประมาณซิลิกอนหรือละเมิดประนีประนอมระบบอื่น ๆ . นี่คือการตัดสินใจเชิงกลยุทธ์มากคนหนึ่งที่ออกแบบ CPU ควรตั้งอยู่บนพื้นฐานความระมัดระวังการวิจัยการทดลองและการจำลอง งานของนักออกแบบ CPU ไม่ได้ที่จะสร้างชุดการเรียนการสอนที่ดีที่สุด แต่จะสร้างชุดการเรียนการสอนที่ดีที่สุดที่ได้รับข้อ จำกัด ทั้งหมด
เมื่อคุณตัดสินใจที่คำแนะนำที่คุณต้องการรวมไว้ใน (เริ่มต้น) ของชุดคำสั่งขั้นตอนต่อไปคือการกำหนด opcodes สำหรับพวกเขา ขั้นตอนแรกคือการจัดกลุ่มคำแนะนำของคุณเป็นชุดโดยลักษณะทั่วไปของคำแนะนำเหล่านั้น ตัวอย่างเช่นคําสั่ง ADD อาจจะให้การสนับสนุนชุดเดียวกันที่แน่นอนของตัวถูกดำเนินการตามคําสั่ง SUB ดังนั้นมันทำให้รู้สึกที่จะนำทั้งสองคำแนะนำในกลุ่มเดียวกัน ในมืออื่น ๆ ที่การเรียนการสอนไม่ได้มักจะต้องถูกดำเนินการเพียงคนเดียว
4เช่นเดียวกับการเรียนการสอน NEG ดังนั้นคุณอาจต้องการใส่ทั้งสองคำแนะนำในกลุ่มเดียวกัน แต่กลุ่มที่แตกต่างกันกว่า ADD และ SUB
เมื่อคุณได้จัดกลุ่มคำแนะนำของคุณทุกขั้นตอนต่อไปคือการเข้ารหัสพวกเขา เข้ารหัสโดยทั่วไปจะใช้บิตบางอย่างที่จะเลือกกลุ่มการเรียนการสอนตกอยู่ในนั้นมันจะใช้บิตบางอย่างที่จะเลือกการเรียนการสอนโดยเฉพาะอย่างยิ่งจากกลุ่มนั้นและมันจะใช้บิตบางส่วนในการกำหนดประเภทของตัวถูกดำเนินการเรียนการสอนที่ช่วยให้ (เช่นลงทะเบียนที่ สถานที่หน่วยความจำและค่าคงที่) จำนวนบิตที่จำเป็นในการเข้ารหัสข้อมูลทั้งหมดนี้อาจจะมีผลกระทบโดยตรงต่อการเรียนการสอนของขนาดโดยไม่คำนึงถึงความถี่ของการเรียนการสอน ตัวอย่างเช่นถ้าคุณต้องการสองบิตเพื่อเลือกกลุ่มสี่บิตเพื่อเลือกการเรียนการสอนในกลุ่มนั้นและหกบิตเพื่อระบุประเภทตัวถูกดำเนินการเรียนการสอนของคุณจะไม่เหมาะสมกับการเรียนการสอนนี้ใน opcode แปดบิต
ในทางตรงกันข้ามถ้าทั้งหมดที่คุณต้องการจริงๆที่จะทำคือการผลักดันให้เป็นหนึ่งในแปดลงทะเบียนที่แตกต่างกันบนสแต็คที่คุณสามารถใช้สี่บิตเพื่อเลือกคำสั่ง PUSH และสามบิตเพื่อเลือกการลงทะเบียน (สมมติว่าการเข้ารหัสในรูปที่ 5.2แปดและ HO บิตจะต้องมีศูนย์)
การเข้ารหัสตัวถูกดำเนินการอยู่เสมอปัญหาเพราะคำแนะนำหลายช่วยให้จำนวนมากของตัวถูกดำเนินการ ยกตัวอย่างเช่นการเรียนการสอน 80x86 MOV ทั่วไปต้อง opcode สองไบต์
5 . แต่ Intel สังเกตเห็นว่า "การเคลื่อนไหว (DISP, EAX);" และ "MOV (EAX, DISP);" คำแนะนำที่เกิดขึ้นบ่อยมากดังนั้นพวกเขาจึงสร้างรุ่นหนึ่งไบต์พิเศษของคำสั่งเพื่อลดขนาดของมันและดังนั้นขนาดของโปรแกรมเหล่านั้นที่ใช้คำสั่งนี้บ่อย ทราบว่าอินเทลไม่ได้ลบรุ่นสองไบต์ของคำแนะนำเหล่านี้ พวกเขามีสองคำแนะนำที่แตกต่างกันที่จะจัดเก็บในหน่วยความจำ EAX หรือโหลด EAX จากหน่วยความจำ คอมไพเลอร์หรือแอสเซมมักจะปล่อยสั้นของทั้งสองคำแนะนำเมื่อได้รับตัวเลือกที่สองหรือมากกว่าคำสั่งที่ลมขึ้นทำสิ่งเดียวกัน
ขอให้สังเกตที่สำคัญการปิดอินเทลทำด้วยการเรียนการสอน MOV พวกเขาให้ขึ้น opcode พิเศษเพื่อที่จะให้รุ่นสั้นของหนึ่งในคำแนะนำ MOV ที่จริงแล้วอินเทลใช้เคล็ดลับนี้ทั่วสถานที่ในการสร้างที่สั้นและง่ายต่อการถอดรหัสคำแนะนำ กลับในปี 1978 นี้คือการประนีประนอมที่ดี (การลดจำนวนรวมของคำแนะนำที่เป็นไปได้ขณะที่ยังลดขนาดโปรแกรม) วันนี้นักออกแบบซีพียูอาจจะต้องการที่จะใช้ opcodes ซ้ำซ้อนเหล่านั้นเพื่อวัตถุประสงค์ที่แตกต่างกัน แต่การตัดสินใจของ Intel เป็นที่เหมาะสมในเวลานั้น (ได้รับค่าใช้จ่ายสูงของหน่วยความจำในปี 1978)
เพื่อส่งเสริมการสนทนานี้เราต้องทำงานกับตัวอย่าง ดังนั้นส่วนถัดไปจะผ่านกระบวนการของการออกแบบการเรียนการสอนที่ง่ายมากตั้งเป็นวิธีการแสดงให้เห็นถึงขั้นตอนนี้
เพราะของการปรับปรุงที่เกิดขึ้นกับโปรเซสเซอร์ตระกูล 80x86 ปีที่ผ่านมาเป้าหมายของอินเทลออกแบบในปี 1978 และความก้าวหน้าในสถาปัตยกรรมคอมพิวเตอร์ที่เกิดขึ้นในช่วงหลายปีที่การเข้ารหัสของคำแนะนำ 80x86 เป็นอย่างมากที่ซับซ้อนและค่อนข้างไร้เหตุผล ดังนั้น 80x86 ไม่ได้เป็นผู้สมัครที่ดีสำหรับสถาปัตยกรรมตัวอย่างเช่นเมื่อพูดถึงวิธีการออกแบบและการเข้ารหัสชุดคำสั่ง อย่างไรก็ตามตั้งแต่นี้เป็นข้อความเกี่ยวกับการเขียนโปรแกรม 80x86 ภาษาประกอบความพยายามที่จะนำเสนอการเข้ารหัสสำหรับบางหน่วยประมวลผลที่โลกแห่งความจริงที่เรียบง่ายไม่ได้ทำให้ความรู้สึก ดังนั้นเราจะหารือเกี่ยวกับการออกแบบชุดคำสั่งในสองขั้นตอนแรกเราจะพัฒนาง่าย (เล็กน้อย) ชุดคำสั่งสำหรับการประมวลผลสมมุติว่าเป็นส่วนเล็ก ๆ ของ 80x86 แล้วเราจะขยายการสนทนาของเรากับชุดคำสั่ง 80x86 เต็ม หน่วยประมวลผลสมมุติของเราไม่ได้ CPU 80x86 จริงดังนั้นเราจะเรียกมันว่าหน่วยประมวลผล Y86 เพื่อหลีกเลี่ยงการสมาคมอุบัติเหตุใด ๆ กับ Intel x86 ครอบครัว
หน่วยประมวลผล Y86 เป็น
มากปล้นลงรุ่นของซีพียู x 86 แรกของทั้งหมด Y86 สนับสนุนเฉพาะขนาดตัวถูกดำเนินการอย่างใดอย่างหนึ่ง - 16 บิตความเรียบง่ายนี้ปลดปล่อยเราจากที่มีการเข้ารหัสขนาดของตัวถูกดำเนินการเป็นส่วนหนึ่งของ opcode (ซึ่งจะช่วยลดจำนวนของ opcodes เราจะต้อง)ความเรียบง่ายก็คือว่าหน่วยประมวลผล Y86 สนับสนุนเพียงสี่ 16 บิตลงทะเบียน: AX, BX, CX, และ DX นี้จะช่วยให้เราเข้ารหัสตัวถูกดำเนินการลงทะเบียนมีเพียงสองบิต (เมื่อเทียบกับสามบิตครอบครัว 80x86 ต้องใช้การเข้ารหัสแปดลงทะเบียน) สุดท้ายโปรเซสเซอร์ Y86 เท่านั้นสนับสนุนรถบัสที่อยู่ 16 บิตพร้อมสูงสุด 65,536 ไบต์ของหน่วยความจำที่ simplifications เหล่านี้บวกกับชุดคำสั่งที่ จำกัด มากจะช่วยให้เราสามารถเข้ารหัสคำแนะนำ Y86 ทั้งหมดที่ใช้ opcode ไบต์เดียวและการเคลื่อนที่สองไบต์ / ชดเชย (ถ้าจำเป็น)
Y86 CPU มี 20 คำแนะนำ เจ็ดคำแนะนำเหล่านี้มีสองตัวถูกดำเนินการแปดคำแนะนำเหล่านี้มีตัวถูกดำเนินการเพียงครั้งเดียวและห้าคำสั่งที่ไม่ถูกดำเนินการในทุก คำแนะนำ MOV (สองรูปแบบ), ADD, SUB, ซีเอ็มพี, AND, OR, NOT, JE, JNE, JB, JBE, JA, JAE, เจเอ็มพี, BRK, IRET, หยุด, GET และ PUT ย่อหน้าต่อไปนี้อธิบายถึงวิธีการทำงานของแต่ละเหล่านี้
การเรียนการสอน MOV เป็นจริงสองชั้นเรียนการเรียนการสอนรวมเข้าไปในการเรียนการสอนเหมือนกัน สองรูปแบบของการเรียนการสอนการเคลื่อนไหวใช้รูปแบบดังต่อไปนี้
MOV (reg / หน่วยความจำ / reg คงที่);
ที่
regใด ๆ ของขวาน, BX, CX หรือ DX;
คงที่เป็นค่าคงที่ที่เป็นตัวเลข (โดยใช้เลขฐานสิบหก) และหน่วยความจำตัวถูกดำเนินการระบุตำแหน่งหน่วยความจำ ส่วนถัดไปจะอธิบายถึงรูปแบบที่เป็นไปได้ถูกดำเนินการหน่วยความจำสามารถใช้ "reg / หน่วยความจำ / คงที่" ตัวถูกดำเนินการจะบอกคุณว่าถูกดำเนินการนี้โดยเฉพาะอาจจะมีการลงทะเบียนที่ตั้งหน่วยความจำหรือคงที่
คำแนะนำทางคณิตศาสตร์และตรรกะใช้รูปแบบดังต่อไปนี้
เพิ่ม (reg / หน่วยความจำ / reg คงที่);
sub (reg / หน่วยความจำ / reg คงที่);
cmp (reg / หน่วยความจำ / คง reg);
และ (reg / หน่วยความจำ / reg คงที่);
หรือ (reg / หน่วยความจำ / reg คงที่);
ไม่ได้ (reg / หน่วยความจำ);
หมายเหตุ: การเรียนการสอนไม่ปรากฏแยกกันเพราะมันอยู่ในระดับที่แตกต่างกว่าคำแนะนำทางคณิตศาสตร์อื่น ๆ (เพราะมันสนับสนุนเฉพาะถูกดำเนินการเดี่ยว)
คําสั่ง ADD เพิ่มมูลค่าของตัวถูกดำเนินการครั้งแรกที่สอง (ลงทะเบียน) ตัวถูกดำเนินการออกจากผลรวมในที่สอง (ลงทะเบียน) ตัวถูกดำเนินการ คําสั่ง SUB ลบค่าของตัวถูกดำเนินการเป็นครั้งแรกจากที่สองออกจากความแตกต่างในตัวถูกดำเนินการที่สอง การเรียนการสอน CMP เปรียบเทียบตัวถูกดำเนินการครั้งแรกกับครั้งที่สองและบันทึกผลของการเปรียบเทียบนี้เพื่อใช้งานกับหนึ่งในคำแนะนำกระโดดเงื่อนไข (อธิบายไว้ในช่วงเวลา) AND และคำแนะนำหรือคำนวณค่าที่เหมาะสมดำเนินการตรรกะที่ตรงกันทั้งสองตัวถูกดำเนินการและจัดเก็บผลในตัวถูกดำเนินการเป็นครั้งแรก การเรียนการสอนไม่ได้ตีความบิตในหน่วยความจำเดียวหรือลงทะเบียนถูกดำเนินการ
คำแนะนำการถ่ายโอนการควบคุมขัดขวางการดำเนินการลำดับของคำสั่งในหน่วยความจำและการควบคุมการถ่ายโอนไปยังจุดอื่น ๆ ในหน่วยความจำอย่างใดอย่างหนึ่งโดยไม่มีเงื่อนไขหรือหลังจากการทดสอบผลของคำสั่งก่อนหน้านี้ซีเอ็มพี คำแนะนำเหล่านี้รวมถึงต่อไปนี้:
จา Dest; - กระโดดถ้าข้างต้น (เช่นมากกว่า)
แจปลายทาง; - กระโดดถ้าข้างต้นหรือเท่ากับ (คือมากกว่าหรือเท่ากับ)
JB Dest; - กระโดดหากราคาต่ำกว่า (เช่นน้อยกว่า)
JBE Dest; - กระโดดหากราคาต่ำกว่าหรือเท่ากับ (คือน้อยกว่าหรือเท่ากับ)
เจ๊ปลายทาง; - กระโดดถ้าเท่ากัน
ฯลฯ Dest; - กระโดดถ้าไม่เท่ากัน
JMP Dest; - กระโดดไม่มีเงื่อนไข
IRET; - อัตราผลตอบแทนจากการขัดจังหวะ
คำแนะนำแรกที่หกให้คุณตรวจสอบผลการเรียนการสอนของซีเอ็มพีก่อนหน้านี้นานกว่า, มากกว่าหรือเท่ากับน้อยกว่าน้อยกว่าหรือเท่ากับความเสมอภาคหรือความไม่เท่าเทียมกัน
6 . ตัวอย่างเช่นถ้าคุณเปรียบเทียบขวานและ BX ลงทะเบียนกับ "ซีเอ็มพี (ขวาน BX);" การเรียนการสอนและดำเนินการเรียนการสอน JA, Y86 CPU จะข้ามไปยังสถานที่ปลายทางที่ระบุถ้าขวานมากกว่า BX ถ้าขวานไม่ได้มากกว่า BX ควบคุมจะตกผ่านไปการเรียนการสอนต่อไปในโปรแกรม
คําสั่ง JMP โดยไม่มีเงื่อนไขการถ่ายโอนการควบคุมเพื่อการเรียนการสอนที่อยู่ปลายทาง IRET ผลตอบแทนการเรียนการสอนการควบคุมจากประจำบริการขัดจังหวะซึ่งเราจะหารือในภายหลัง
แถมและคำแนะนำการใส่ให้คุณอ่านและเขียนค่าจำนวนเต็ม GET จะหยุดและแจ้งให้ผู้ใช้สำหรับค่าฐานสิบหกแล้วเก็บค่าที่เป็นขวานลงทะเบียน แสดง PUT (ในเลขฐานสิบหก) ค่าของขวานลงทะเบียน
คำแนะนำที่เหลือไม่จำเป็นต้องถูกดำเนินการใด ๆ ที่พวกเขาจะหยุดและ BRK หยุดยุติการทำงานของโปรแกรมและ BRK หยุดโปรแกรมในรัฐที่จะสามารถเริ่มต้นใหม่
โปรเซสเซอร์ Y86 ต้อง opcode ไม่ซ้ำกันสำหรับการเรียนการสอนที่แตกต่างกันทุกครั้งไม่เพียง แต่การเรียนการสอน แม้ "MOV (BX ขวาน);" และ "MOV (CX, ขวาน);" มีทั้งที่อยู่ในระดับเดียวกันที่พวกเขาจะต้องมีความแตกต่างกันถ้า opcodes CPU คือการแยกความแตกต่างของพวกเขา อย่างไรก็ตามก่อนที่จะมองไปที่ทุก opcodes ที่เป็นไปได้อาจจะจะเป็นความคิดที่ดีที่จะเรียนรู้เกี่ยวกับตัวถูกดำเนินการเป็นไปได้สำหรับคำแนะนำเหล่านี้
3.1 โหมดที่อยู่ใน Y86
คำแนะนำ Y86 ใช้ห้าชนิดที่แตกต่างกันถูกดำเนินการ: ลงทะเบียนค่าคงที่และหน่วยความจำที่อยู่สามรูปแบบ รูปแบบที่แต่ละคนจะเรียกว่า
โหมด . หน่วยประมวลผล Y86 สนับสนุน
ลงทะเบียนที่อยู่โหมด
7 ,
ทันทีโหมด,
อ้อมโหมด,
การจัดทำดัชนีโหมดและ
ตรงโหมด ย่อหน้าต่อไปนี้อธิบายแต่ละโหมดเหล่านี้
ตัวถูกดำเนินการลงทะเบียนเป็นที่ง่ายที่สุดที่จะเข้าใจ พิจารณารูปแบบการเรียนการสอนต่อไปนี้ MOV:
การเรียนการสอนครั้งแรกสำเร็จไม่มีอะไรแน่นอน เป็นชุดค่าจากขวานลงทะเบียนกลับเข้าไปในขวานลงทะเบียน ที่เหลืออีกสามคำแนะนำคัดลอกค่าของ BX, CX และ DX เป็นขวาน ทราบว่าคำแนะนำเหล่านี้ออกจาก BX, CX, และ DX ไม่เปลี่ยนแปลง ตัวถูกดำเนินการที่สอง (ปลายทาง) ไม่ได้ จำกัด อยู่ที่ขวาน;
คุณสามารถย้ายค่าใด ๆ ของการลงทะเบียนเหล่านี้
นอกจากนี้ยังมีค่าคงที่สวยง่ายที่จะจัดการกับ พิจารณาคำแนะนำดังต่อไปนี้
คำแนะนำเหล่านี้เป็นสิ่งที่ตรงไปตรงสวย; พวกเขาโหลดลงทะเบียนของตนมีค่าคงที่เลขฐานสิบหกที่ระบุ
8 .
มีสามโหมดที่อยู่ที่เกี่ยวข้องกับการเข้าถึงข้อมูลในหน่วยความจำ คำแนะนำต่อไปนี้แสดงให้เห็นถึงการใช้โหมดเหล่านี้ที่อยู่:
การเรียนการสอนครั้งแรกที่ด้านบนใช้โหมดโดยตรงในการโหลดขวานมีค่า 16 บิตที่เก็บไว้ในหน่วยความจำเริ่มต้นที่สถานที่ตั้ง $ 1,000
"การเคลื่อนไหว ([BX] ขวาน);" การเรียนการสอนโหลดขวานจากที่ตั้งหน่วยความจำที่ระบุโดยเนื้อหาของ BX ลงทะเบียน นี้เป็นโหมดที่อยู่ทางอ้อมแทนที่จะใช้ค่าใน BX คำแนะนำนี้เข้าถึงตำแหน่งหน่วยความจำที่มีอยู่ปรากฏใน BX โปรดทราบว่าต่อไปนี้สองคำแนะนำ:
แน่นอนลำดับที่สองเป็นที่นิยม แต่มีหลายกรณีที่การใช้ความร้ายเร็วสั้นกว่าและดีกว่า เราจะเห็นตัวอย่างบางส่วนของเล็ก ๆ น้อย ๆ ในภายหลัง
โหมดหน่วยความจำที่ผ่านมาที่อยู่มี
การจัดทำดัชนีโหมด ตัวอย่างของหน่วยความจำนี้โหมดเป็น
การเรียนการสอนนี้จะเพิ่มเนื้อหาของ BX กับ $ 1,000 ในการผลิตที่อยู่ของมูลค่าหน่วยความจำในการเรียกข้อมูล คำสั่งนี้จะมีประโยชน์สำหรับการเข้าถึงองค์ประกอบของอาร์เรย์บันทึกและโครงสร้างข้อมูลอื่น ๆ
3.2 คำแนะนำการเข้ารหัส Y86
แม้ว่าเราจะสามารถกำหนดโดยพล opcodes แต่ละคำแนะนำ Y86, เก็บไว้ในใจว่า CPU จริงใช้วงจรตรรกะที่จะถอดรหัส opcodes และการกระทำที่เหมาะสมกับพวกเขา opcode CPU โดยทั่วไปจะใช้จำนวนหนึ่งของบิตใน opcode เพื่อแสดงว่าการเรียนการสอนในชั้นเรียน (เช่น, MOV, ADD, SUB) และจำนวนที่แน่นอนของบิตการเข้ารหัสแต่ละตัวถูกดำเนินการ
การเรียนการสอน Y86 ทั่วไปใช้รูปแบบที่แสดงใน
รูปที่ 5.3 . การเรียนการสอนขั้นพื้นฐานเป็นคนใดคนหนึ่งหรือสามไบต์นาน opcode การเรียนการสอนประกอบด้วย byte เดียวที่มีสามช่อง สนามแรก HO สามบิตกำหนดการเรียนการสอน นี้จะให้แปดรวม ในขณะที่คุณอาจจำมี 20 คำแนะนำที่แตกต่างกัน เราไม่สามารถเข้ารหัส 20 คำแนะนำกับสามบิตดังนั้นเราจะต้องดึงเทคนิคบางอย่างที่จะจัดการกับคำแนะนำอื่น ๆ ในขณะที่คุณสามารถเห็นใน
ภาพที่ 5.3 , opcode พื้นฐาน encodes คำแนะนำ MOV (สองคำแนะนำหนึ่งที่
RRข้อมูลระบุปลายทางหนึ่งที่
mmmข้อมูลระบุปลายทาง) และ ADD, SUB, ซีเอ็มพีและและหรือ คำแนะนำ : มีหนึ่งด้านการเรียนการสอนเพิ่มเติมเป็น
พิเศษ . การเรียนการสอนในชั้นเรียนพิเศษมีกลไกที่ช่วยให้เราสามารถขยายจำนวนของการเรียนการสอนที่มีอยู่เราจะกลับไป opcode การขยายตัวนี้ไม่นาน
รูปที่ 3 การเรียนการสอนขั้นพื้นฐาน Y86 การเข้ารหัส
เพื่อตรวจสอบ opcode การเรียนการสอนโดยเฉพาะอย่างยิ่งของคุณต้องการเพียงเลือกบิตที่เหมาะสมสำหรับ
iii ,
RRและ
mmmสาขา
RRข้อมูลมีทะเบียนปลายทาง (ยกเว้นคำสั่ง MOV ที่มี
iiiข้อมูลคือ% 111) และ
mmmข้อมูลเข้ารหัสถูกดำเนินการแหล่งที่มา ตัวอย่างเช่นในการเข้ารหัส "MOV (BX ขวาน);" การเรียนการสอนที่คุณจะเลือก
iii = 110 ("MOV (reg, reg);)
RR = 00 (ขวาน) และ
mmm . = 001 (BX) นี้ผลิตหนึ่งไบต์การเรียนการสอน% 11,000,001 หรือ $ C0
คำแนะนำ Y86 ต้องมากกว่าหนึ่งไบต์ ยกตัวอย่างเช่นการเรียนการสอน "การเคลื่อนไหว ([1000], ขวาน);" โหลดลงทะเบียนขวานจากหน่วยความจำสถานที่ $ 1,000 การเข้ารหัสสำหรับ opcode คือ% 11000110 หรือ $ C6 อย่างไรก็ตามการเข้ารหัสสำหรับ "การเคลื่อนไหว ([2000], ขวาน);"opcode การเรียนการสอนเป็นยัง $ C6 เห็นได้ชัดว่าทั้งสองคำแนะนำทำสิ่งที่แตกต่างกันอย่างใดอย่างหนึ่งโหลดลงทะเบียนขวานจากหน่วยความจำสถานที่ $ 1,000 ในขณะที่โหลดอื่น ๆ ที่ลงทะเบียนขวานจากหน่วยความจำสถานที่ $ 2,000 การเข้ารหัสที่อยู่สำหรับ [xxxx] หรือ [xxxx + BX] โหมดที่อยู่หรือการเข้ารหัสคงที่สำหรับโหมดทันทีคุณต้องทำตาม opcode กับที่อยู่ 16 บิตหรือคงที่กับไบต์ LO ทันทีดังต่อไปนี้ opcode ในหน่วยความจำและไบต์ HO หลังจากนั้น ดังนั้นการเข้ารหัสสามไบต์สำหรับ "การเคลื่อนไหว ([1000], ขวาน);" จะเป็น $ C6, $ 00, $ 10 และการเข้ารหัสสามไบต์สำหรับ "การเคลื่อนไหว ([2000], ขวาน);" จะเป็น $ C6, $ 00, $ 20
พิเศษ opcode ช่วยให้ x86 CPU ที่จะขยายชุดของคำสั่งที่มีอยู่ opcode นี้จัดการหลายศูนย์และหนึ่งตัวถูกดำเนินการคำแนะนำดังแสดงใน
รูปที่ 5.4และ
รูปที่ 5.5 .
รูปที่ 5.4 โสดถูกดำเนินการเข้ารหัสการเรียนการสอน
รูปที่5 การเข้ารหัสถูกดำเนินการเป็นศูนย์การเรียนการสอน
มีสี่หนึ่งตัวถูกดำเนินการเรียนการสอนมี การเข้ารหัสแรก (00) ต่อขยายชุดคำสั่งที่มีชุดคำสั่งศูนย์ตัวถูกดำเนินการ (ดู
รูปที่ 5 ) opcode ที่สองยังเป็น opcode การขยายตัวที่ให้ทุก Y86
กระโดดคำแนะนำ (ดู
รูปที่ 5.6 ) opcode ที่สามคือการเรียนการสอนไม่ได้ นี้เป็นบิตตรรกะการดำเนินงานไม่ว่าตีความบิตทั้งหมดในการลงทะเบียนปลายทางหรือหน่วยความจำตัวถูกดำเนินการ สี่ opcode เดียวที่ไม่ได้กำหนดเป็นตัวถูกดำเนินการอยู่ในปัจจุบัน ความพยายามที่จะดำเนินการ opcode นี้ใด ๆ ที่จะหยุดการประมวลผลที่มีข้อผิดพลาดการเรียนการสอนที่ผิดกฎหมาย นักออกแบบซีพียูมักจะสงวน opcodes ที่ไม่ได้กำหนดอย่างหนึ่งในการขยายชุดคำสั่งวันที่ในอนาคต (ที่อินเทลได้เมื่อย้ายจากหน่วยประมวลผล 80286 ถึง 80386) นี้
รูปที่ 6 กระโดดการเข้ารหัสการเรียนการสอน
มีเจ็ดคำแนะนำกระโดดในชุดคำสั่ง x86 เป็น พวกเขาทั้งหมดจะใช้รูปแบบต่อไปนี้
JMP สำเนาคำสั่งค่า 16 บิต (ที่อยู่) ต่อไปนี้ opcode ลงทะเบียนไอพี ดังนั้น CPU จะเรียกคำสั่งถัดจากที่อยู่เป้าหมายนี้ ได้อย่างมีประสิทธิภาพโครงการ "กระโดด" จากจุดที่คําสั่ง JMP เพื่อการเรียนการสอนที่อยู่ที่เป้าหมาย
คําสั่ง JMP เป็นตัวอย่างของการเรียนการสอนกระโดดไม่มีเงื่อนไข มันก็จะถ่ายโอนการควบคุมไปยังที่อยู่ของเป้าหมาย ที่เหลืออีกหกคำแนะนำคำแนะนำกระโดดเงื่อนไข พวกเขาทดสอบสภาพบางอย่างและกระโดดถ้าเงื่อนไขเป็นจริง พวกเขาตกผ่านไปการเรียนการสอนต่อไปถ้าเงื่อนไขเป็นเท็จ คำแนะนำเหล่านี้หก, JA, JAE, JB, JBE, JE และ JNE ให้คุณทดสอบมากขึ้นกว่ามากกว่าหรือเท่ากับน้อยกว่าน้อยกว่าหรือเท่ากับความเสมอภาคและความไม่เท่าเทียม คุณมักจะดำเนินการคำแนะนำเหล่านี้ทันทีหลังจากที่การเรียนการสอน CMP ตั้งแต่มันตั้งน้อยกว่าและความเท่าเทียมกันธงที่ผลการทดสอบคำแนะนำกระโดดเงื่อนไข ทราบว่ามีแปด opcodes กระโดดไปได้มี แต่ x 86 ใช้เพียงเจ็ดของพวกเขา opcode แปดเป็นอีกหนึ่ง opcode ที่ผิดกฎหมาย
กลุ่มสุดท้ายของคำแนะนำคำแนะนำศูนย์ถูกดำเนินการปรากฏใน
ภาพที่ 5.5 . สามคำแนะนำเหล่านี้เป็นคำสั่งที่ผิดกฎหมาย opcodes BRK (พัก) การเรียนการสอนของ CPU หยุดจนกว่าผู้ใช้จะเริ่มต้นใหม่ด้วยตนเองได้ นี้จะเป็นประโยชน์สำหรับการหยุดโปรแกรมระหว่างการดำเนินการในการสังเกตผลIRET (กลับขัดจังหวะ) การเรียนการสอนการควบคุมผลตอบแทนจากบริการประจำขัดจังหวะ เราจะหารือเกี่ยวกับขั้นตอนการให้บริการการขัดจังหวะในภายหลัง โปรแกรมหยุดยุติการทำงานของโปรแกรม การเรียนการสอนแถมอ่านค่าฐานสิบหกจากผู้ใช้และผลตอบแทนค่าในขวานลงทะเบียนนี้ การเรียนการสอน PUT ออกค่าในขวานลงทะเบียน
3.3 คำแนะนำการเข้ารหัสมือ
เก็บไว้ในใจว่าหน่วยประมวลผล Y86 เรียกคำแนะนำเป็นรูปแบบบิตจากหน่วยความจำ มันถอดรหัสและดำเนินการรูปแบบบิตเหล่านั้น หน่วยประมวลผลที่ไม่ดำเนินการคำแนะนำของรูปแบบ "การเคลื่อนไหว (ขวาน BX);" (นั่นคือสตริงของตัวอักษรที่สามารถอ่านได้โดยมนุษย์) แต่จะดำเนินการรูปแบบบิต $ C1 จากหน่วยความจำ คำแนะนำเช่น "MOV (ขวาน BX);" และ "เพิ่ม (5, CX);" เป็นตัวแทนมนุษย์สามารถอ่านคำแนะนำเหล่านี้ที่เราต้องแปลงเป็น
รหัสเครื่อง (นั่นคือการเป็นตัวแทนไบนารีการเรียนการสอนว่าเครื่องจริงรัน) ในส่วนนี้เราจะสำรวจวิธีการด้วยตนเองทํางานนี้
ขั้นตอนแรกคือการเลือกคำสั่งเพื่อแปลงเป็นรหัสเครื่อง เราจะเริ่มต้นด้วยการเป็นตัวอย่างที่ง่ายมาก "เพิ่ม (CX, DX);" การเรียนการสอน เมื่อคุณได้เลือกคำสั่งที่คุณมองขึ้นไปการเรียนการสอนในหนึ่งในร่างของส่วนก่อนหน้านี้ คําสั่ง ADD อยู่ในกลุ่มแรก (ดู
รูปที่ 5.3 ) และมี
คสาขา% 101 ถูกดำเนินการมาเป็น CX ดังนั้น
mmmข้อมูลคือ% 010 และถูกดำเนินการปลายทางเป็น DX เพื่อ
RRข้อมูลคือ% 11 ผสานบิตเหล่านี้ผลิต opcode% 10111010 หรือ $ ปริญญาตรี
รูปที่ 5.7 การเข้ารหัส ADD (CX, DX);
ตอนนี้พิจารณา "เพิ่ม (5, ขวาน);" การเรียนการสอน ตั้งแต่การเรียนการสอนนี้มีแหล่งที่มาถูกดำเนินการทันทีฟิลด์ mmm จะ% 111 ตัวถูกดำเนินการลงทะเบียนปลายทางขวาน (00%) ดังนั้น opcode เต็มกลายเป็น 10,100,111 $ หรือ $ A7 อย่างไรก็ตามโปรดทราบว่านี้ไม่ได้ดำเนินการเข้ารหัสของการเรียนการสอน นอกจากนี้เรายังต้องรวมถึง 16 บิตคงที่ $ 0005 เป็นส่วนหนึ่งของการเรียนการสอน เข้ารหัสไบนารีคงต้องปฏิบัติตามทันที opcode ในหน่วยความจำเพื่อให้ลำดับของไบต์ในหน่วยความจำ (จากที่อยู่ที่ต่ำไปยังที่อยู่ที่สูงที่สุด) คือ $ A7, $ 05, $ 00 ทราบว่าไบต์ LO คงดังต่อไปนี้ opcode และไบต์ HO คงดังต่อไปนี้ไบต์ LO ลำดับนี้จะปรากฏขึ้นหลังเพราะไบต์ที่ถูกจัดอยู่ในลำดับที่อยู่ของการเพิ่มหน่วยความจำและไบต์ HO คงที่จะปรากฏในที่อยู่หน่วยความจำสูงสุด
รูปที่ 8 การเข้ารหัส ADD (5, ขวาน);
"เพิ่ม ([2FF + BX], CX);" นอกจากนี้ยังมีการเรียนการสอนอย่างต่อเนื่อง 16 บิตที่เกี่ยวข้องกับการเข้ารหัสการเรียนการสอนของ - ส่วนการกำจัดของโหมดการจัดทำดัชนี การเข้ารหัสการเรียนการสอนนี้เราจะใช้ค่าฟิลด์ต่อไปนี้:
iii =% 101,
RR = 10% และ
mmm = 101% นี้ผลิต opcode ไบต์% 10110101 หรือ $ B5 การเรียนการสอนที่สมบูรณ์ยังต้องคงที่ $ 2FF เพื่อให้การเรียนการสอนเต็มรูปแบบสามไบต์ลำดับ $ B5, $ FF, $ 02
รูปที่ 5.9 การเข้ารหัส ADD ([$ 2FF + BX], CX);
ตอนนี้พิจารณา "เพิ่ม ([1000], ขวาน);" การเรียนการสอน การเรียนการสอนนี้จะเพิ่มเนื้อหา 16 บิตของหน่วยความจำสถานที่ $ 1,000 และ $ 1,001 มูลค่าในขวานลงทะเบียน อีกครั้ง
iii = 101% สำหรับการเรียนการสอนเพิ่ม ลงทะเบียนปลายทางคือขวานเพื่อ
RR = 00% สุดท้ายโหมดเป็นรางเดียวโหมดดังนั้น
mmm = 110% นี้เป็น opcode% 10100110 หรือ $ A6 การเรียนการสอนเป็นสามไบต์นานเพราะมันต้องเข้ารหัสราง (ที่อยู่) ของสถานที่ตั้งหน่วยความจำในไบต์ที่สองต่อไปนี้ opcode ดังนั้นที่สมบูรณ์ลำดับสามไบต์เป็น $ A6, $ 00, $ 10
รูปที่ 10 การเข้ารหัส ADD ([1000], ขวาน);
โหมดสุดท้ายที่ต้องพิจารณาคือการลงทะเบียนโหมดทางอ้อม [BX] "เพิ่ม ([BX], BX);" การเรียนการสอนจะใช้ค่าการเข้ารหัสต่อไปนี้:
mmm =% 101,
RR = 01% (BX) และ
mmm = 100% ([BX]) ตั้งแต่ค่าใน BX ลงทะเบียนอย่างสมบูรณ์ระบุที่อยู่หน่วยความจำที่มีความจำเป็นในด้านการกำจัดไม่มี ดังนั้นการเรียนการสอนนี้เป็นเพียงหนึ่งไบต์นาน
รูปที่ 5.11 การเข้ารหัส ADD ([BX], BX); การเรียนการสอน
คุณใช้วิธีการคล้ายการเข้ารหัส SUB, ซีเอ็มพี, และ, และหรือคำแนะนำที่คุณทำคําสั่ง ADD แตกต่างเพียงว่าคุณใช้ค่าที่แตกต่างกันสำหรับ
iiiสนามใน opcode
การเรียนการสอน MOV เป็นพิเศษเพราะมีสองรูปแบบการเรียนการสอน MOV คุณเข้ารหัสรูปแบบแรก (
iii = 110%) ตรงตามที่คุณทำคําสั่ง ADDสำเนาแบบฟอร์มนี้คงที่หรือข้อมูลจากหน่วยความจำหรือลงทะเบียน (
mmmสนาม) ลงทะเบียนหัวข้อ (
RRเขต)
รูปแบบที่สองของการเรียนการสอน MOV (
iii = 111%) คัดลอกข้อมูลจากแหล่งที่มาลงทะเบียน (
RR ) ไปยังสถานที่หน่วยความจำหัวข้อ (ที่
mmmข้อมูลระบุ) ในรูปแบบของการเรียนการสอน MOV นี้ความหมายแหล่งปลายทาง / ของ
RRและ
mmmสาขาที่จะกลับเพื่อให้
RRเป็นเขตแหล่งที่มาและ
mmmเป็นเขตปลายทาง ความแตกต่างก็คือว่า
mmmข้อมูลอาจมีค่า 100% ([BX]) 101% ([DISP + BX]) และ% 110 ([DISP]) ค่าสถานที่ไม่สามารถเป็น 000% .. 011% (ลงทะเบียน) หรือ% 111 (คงที่) เหล่านี้หลังห้าเข้ารหัสที่ผิดกฎหมาย (ตามคำแนะนำสถานที่ลงทะเบียนจะถูกจัดการโดยการเรียนการสอน MOV อื่น ๆ และการจัดเก็บข้อมูลลงคงไม่ได้ทำให้ความรู้สึกใด ๆ )
หน่วยประมวลผล Y86 สนับสนุนคำสั่งเดียวกับหน่วยความจำเดียว / ลงทะเบียนถูกดำเนินการ - การเรียนการสอนไม่ได้ การเรียนการสอนไม่ได้มีรูปแบบ: "ไม่ได้ (reg);" หรือ "ไม่ได้ (ข่าว);" ข่าวที่เป็นหนึ่งในรูปแบบที่อยู่หน่วยความจำ ([BX], [DISP + BX] หรือ [DISP]) ทราบว่าคุณอาจไม่ได้ระบุค่าคงที่เป็นตัวถูกดำเนินการของการเรียนการสอนไม่ได้
ตั้งแต่การเรียนการสอนไม่ได้มีเพียงตัวถูกดำเนินการเดียวก็เพียงใช้สนาม mmm การเข้ารหัสตัวถูกดำเนินการนี้
RRสนามรวมกับ
iiiเขตเลือกไม่ได้การเรียนการสอน (
iii = 000% และ
RR = 10%) เมื่อใดก็ตามที่
iiiข้อมูลมีศูนย์นี้จะบอก CPU ที่ถอดรหัสพิเศษเป็นสิ่งจำเป็นสำหรับการเรียนการสอน ในกรณีนี้
RRข้อมูลระบุว่าเรามีการเรียนการสอนไม่ได้หรือหนึ่งในคำแนะนำถอดรหัสพิเศษอื่น ๆ
การเข้ารหัสการเรียนการสอนเช่น "ไม่ได้ (ขวาน);" คุณก็จะระบุ% 000
iiiและ 10% สำหรับ
RRสาขา แล้วคุณจะเข้ารหัส
mmmสนามเช่นเดียวกับที่คุณจะเข้ารหัสข้อมูลนี้สำหรับการเรียนการสอนเพิ่ม ตั้งแต่
mmm = 000% สำหรับขวาน, การเข้ารหัสของ "ไม่ได้ (ขวาน);" จะ% 00010000 หรือ $ 10
รูปที่ 12 การเข้ารหัสไม่ (ขวาน); การเรียนการสอน
การเรียนการสอนไม่ไม่อนุญาตให้ทันที (คงที่) ตัวถูกดำเนินการจึง opcode% 00,010,111 ($ 17) เป็น opcode ที่ผิดกฎหมาย
Y86 คำแนะนำกระโดดเงื่อนไขยังใช้การเข้ารหัสพิเศษ คำแนะนำเหล่านี้มักจะมีสามไบต์นาน ไบต์แรก (opcode) ระบุซึ่งกระโดดเงื่อนไขการเรียนการสอนที่จะดำเนินการและสองไบต์ต่อไประบุตำแหน่งที่โอน CPU ถ้าเงื่อนไขเป็นไปตาม มีเจ็ดคำแนะนำกระโดด Y86 ที่แตกต่างกันหกกระโดดเงื่อนไขและเป็นหนึ่งกระโดดไม่มีเงื่อนไขเป็น คำแนะนำเหล่านี้ตั้ง
mmm =% 000
RR = 01% และใช้
mmmสนามเพื่อเลือกหนึ่งในการกระโดดไปได้เจ็ด;opcode เป็นไปได้ที่แปดเป็น opcode ที่ผิดกฎหมาย (ดู
รูปที่ 5.6 ) การเข้ารหัสคำแนะนำเหล่านี้เป็นที่ค่อนข้างตรงไปข้างหน้า เมื่อคุณได้รับการเรียนการสอนที่คุณต้องการเข้ารหัสคุณได้กำหนด opcode (เนื่องจากมี opcode เดียวสำหรับแต่ละคำสั่ง) ค่า opcode ตกอยู่ในช่วง 08 $ .. $ 0E ($ 0F เป็น opcode ผิดกฎหมาย)
ข้อมูลเดียวที่ต้องใช้ความคิดบางอย่างที่เป็นตัวถูกดำเนินการ 16 บิตที่ตาม opcode สนามนี้ถือเป็นที่อยู่ของการเรียนการสอนเป้าหมายที่ (UN) การถ่ายโอนกระโดดเงื่อนไขถ้าเงื่อนไขเป็นจริง (เช่น, JE ถ่ายโอนการควบคุมไปยังที่อยู่นี้หากมีการเรียนการสอน CMP หน้าที่แล้วพบว่าทั้งสองตัวถูกดำเนินการของตนเท่ากับ) ที่จะต้องเข้ารหัสข้อมูลนี้คุณจะต้องทราบที่อยู่ของไบต์ opcode การเรียนการสอนเป้าหมาย ถ้าคุณได้แปลงแล้วการเรียนการสอนในรูปแบบไบนารีและเก็บไว้ในหน่วยความจำนี้ไม่ได้เป็นปัญหา เพียงแค่ระบุที่อยู่ของคำสั่งที่เป็นตัวถูกดำเนินการของการกระโดดสภาพ ในทางตรงกันข้ามถ้าคุณยังไม่ได้เขียนยังแปลงและวางการเรียนการสอนที่เป็นหน่วยความจำที่รู้ที่อยู่ของมันก็ดูเหมือนจะต้องมีบิตของดวงชะตา โชคดีที่คุณสามารถคิดออกอยู่เป้าหมายโดยการคำนวณความยาวของคำแนะนำทั้งหมดระหว่างการเรียนการสอนกระโดดในปัจจุบันที่คุณกำลังการเข้ารหัสและการสอนเป้าหมาย แต่น่าเสียดายที่นี้เป็นงานที่ยากลำบาก ทางออกที่ดีที่สุดคือการเขียนคำแนะนำทั้งหมดของคุณลงบนกระดาษคำนวณความยาวของพวกเขา (ซึ่งเป็นเรื่องง่ายคำแนะนำทั้งหมดเป็นหนึ่งหรือสามไบต์ยาวขึ้นอยู่กับการปรากฏตัวของตัวถูกดำเนินการ 16 บิต) และกำหนดที่อยู่ที่เหมาะสมกับแต่ละคำสั่ง . เมื่อคุณได้กระทำเช่นนี้ (และสมมติว่าคุณยังไม่ได้ทำผิดพลาดใด ๆ ) คุณจะรู้ว่าที่อยู่เริ่มต้นสำหรับแต่ละคำสั่งและคุณสามารถกรอกข้อมูลในตัวถูกดำเนินการที่อยู่ในเป้าหมายของคุณ (ยกเลิก) คำแนะนำในการกระโดดตามเงื่อนไขที่คุณเข้ารหัสพวกเขา โชคดีที่มีวิธีที่ดีกว่าการทำเช่นนี้ในขณะที่คุณจะเห็นในส่วนถัดไป
กลุ่มสุดท้ายของคำแนะนำคำแนะนำศูนย์ตัวถูกดำเนินการจะง่ายที่สุดในการเข้ารหัส เนื่องจากพวกเขาไม่มีตัวถูกดำเนินการพวกเขาอยู่เสมอหนึ่งไบต์ยาวและการเรียนการสอนที่ไม่ซ้ำกันระบุ opcode สำหรับการเรียนการสอน คำแนะนำเหล่านี้มักจะมี
iii =% 000
RR = 00% และ
mmmระบุ opcode การเรียนการสอนโดยเฉพาะอย่างยิ่ง (ดู
รูปที่ 5.5 ) ทราบว่า Y86 CPU ใบที่สามของคำแนะนำเหล่านี้ไม่ได้กำหนด (เพื่อให้เราสามารถใช้ opcodes เหล่านี้สำหรับการขยายตัวในอนาคต)
3.4 การใช้ประกอบการเข้ารหัสคำแนะนำ
แน่นอนโปรแกรมภาษาเครื่องมือการเข้ารหัสที่แสดงในส่วนก่อนหน้านี้จะทำไม่ได้ทั้งหมด แต่โปรแกรมที่เล็กที่สุด แน่นอนว่าคุณไม่ได้มีการทำอะไรเช่นนี้เมื่อเขียนโปรแกรม HLA คอมไพเลอร์ HLA ช่วยให้คุณสามารถสร้างไฟล์ข้อความที่มีรูปแบบที่อ่านได้ของคำแนะนำ คุณอาจสงสัยว่าทำไมเราสามารถเขียนโค้ดดังกล่าว 80x86 แต่ไม่ใช่สำหรับ Y86 คำตอบคือการใช้แอสเซมหรือคอมไพเลอร์สำหรับ Y86 การปฏิบัติงานของผู้ประกอบ / คอมไพเลอร์คือการอ่านไฟล์ข้อความที่มีข้อความที่อ่านได้ของมนุษย์และแปลข้อความเป็นแทน binary เข้ารหัสที่สำหรับโปรแกรมภาษาเครื่องที่เกี่ยวข้อง
ประกอบหรือคอมไพเลอร์จะไม่มีอะไรพิเศษ มันเป็นเพียงโปรแกรมที่รันในระบบคอมพิวเตอร์ของคุณอีก สิ่งเดียวที่พิเศษเกี่ยวกับผู้ประกอบหรือคอมไพเลอร์คือการที่มันแปลโปรแกรมจากรูปแบบหนึ่ง (source code) ไปยังอีก (รหัสเครื่อง) ประกอบ Y86 ทั่วไปเช่นจะอ่านบรรทัดของข้อความแต่ละบรรทัดที่มีการเรียนการสอน Y86 ก็จะ
แยก9แต่ละคำแล้วเขียนเทียบเท่าไบนารีของแต่ละคำสั่งหน่วยความจำหรือไฟล์สำหรับการดำเนินการในภายหลัง
ประกอบมีสองข้อได้เปรียบใหญ่กว่าการเขียนโปรแกรมในรหัสเครื่อง ครั้งแรกพวกเขาโดยอัตโนมัติแปลสตริงเช่น "ADD (ขวาน BX);" และ "MOV (ขวาน [1000]);" เพื่อรูปแบบไบนารีของพวกเขาที่เกี่ยวข้อง ประการที่สองและอาจจะยิ่งมีความสำคัญมากขึ้นประกอบให้คุณแนบฉลากงบและดูฉลากผู้ที่อยู่ในคำแนะนำกระโดด; นี้หมายความว่าคุณไม่จำเป็นต้องทราบที่อยู่ของเป้าหมายการเรียนการสอนเพื่อที่จะระบุการเรียนการสอนเป็นเป้าหมายของการกระโดดหรือการเรียนการสอนกระโดดเงื่อนไขที่ ผู้ใช้ Windows ที่มีสิทธิ์เข้าถึง Y86 ประกอบง่ายมาก
10ที่ช่วยให้คุณระบุถึง 26 ป้ายในโปรแกรม (ใช้สัญลักษณ์ '' .. 'Z') การติดฉลากในงบคุณก็บทการเรียนการสอนที่มีฉลากและลำไส้ใหญ่เช่น
ในการถ่ายโอนการควบคุมไปยังคำสั่งที่มีป้ายชื่อติดอยู่กับมัน, คุณเพียงแค่ระบุชื่อป้ายเป็นตัวถูกดำเนินการเรียนการสอนกระโดดเช่น
ประกอบจะคำนวณที่อยู่ของฉลากและปฏิบัติตามที่อยู่ของคุณเมื่อใดก็ตามที่คุณระบุป้ายชื่อเป็นตัวถูกดำเนินการของการกระโดดหรือการเรียนการสอนกระโดดเงื่อนไข แอสเซมสามารถทำเช่นนี้แม้ว่าจะยังไม่พบป้ายชื่อในแฟ้มแหล่งที่มาของโปรแกรม (เช่นป้ายชื่อที่แนบมากับการเรียนการสอนต่อไปในแฟ้มแหล่งที่มา) ผู้ประกอบส่วนใหญ่ประสบความสำเร็จมายากลนี้โดยการสองผ่านไปแฟ้มแหล่งที่มา ในช่วงที่ผ่านแรกประกอบเป็นตัวกำหนดที่อยู่เริ่มต้นของแต่ละสัญลักษณ์และเก็บข้อมูลในฐานข้อมูลอย่างง่ายที่เรียกว่า
ตารางสัญลักษณ์ . แอสเซมไม่ได้ปล่อยรหัสเครื่องใด ๆ ในช่วงแรกผ่านนี้ จากนั้นผู้ประกอบทำให้ผ่านที่สองกว่าแฟ้มแหล่งที่มาและที่จริงปล่อยรหัสเครื่อง ในช่วงผ่านที่สองนี้ก็เงยหน้าขึ้นมองอ้างอิงฉลากทั้งหมดในตารางสัญลักษณ์และใช้ข้อมูลจะดึงจากฐานข้อมูลนี้ในการกรอกข้อมูลลงในช่องตัวถูกดำเนินการของคำสั่งที่อ้างถึงสัญลักษณ์บางอย่าง
3.5 ขยายชุด Y86 การเรียนการสอน
Y86 CPU เป็น CPU เล็กน้อยเหมาะสำหรับแสดงให้เห็นถึงวิธีการเข้ารหัสคำแนะนำเครื่อง แต่ชอบใด ๆ CPU ที่ดีการออกแบบ Y86 จะให้ความสามารถในการขยายตัว ดังนั้นถ้าคุณต้องการที่จะปรับปรุงการทำงานโดยการเพิ่มคำสั่งใหม่ความสามารถในการบรรลุเป้าหมายนี้มีอยู่ในชุดคำสั่ง
มีสองวิธีมาตรฐานในการเพิ่มจำนวนของคำแนะนำในชุดคำสั่งของ CPU เป็น กลไกทั้งสองต้องปรากฏตัวของที่ไม่ได้กำหนด (หรือผิดกฎหมาย) opcodes บน CPU ตั้งแต่ Y86 CPU มีหลายเหล่านี้เราสามารถขยายชุดคำสั่ง
วิธีแรกคือการใช้โดยตรง opcodes ไม่ได้กำหนดที่จะกำหนดคำสั่งใหม่ นี้ทำงานได้ดีที่สุดเมื่อมีรูปแบบบิตไม่ได้กำหนดภายในกลุ่ม opcode และการเรียนการสอนใหม่ที่คุณต้องการเพิ่มตกอยู่ในกลุ่มเดียวกันกับที่ ตัวอย่างเช่น 00011mmm% opcode ตกอยู่ในกลุ่มเดียวกับการเรียนการสอนไม่ได้ ถ้าคุณตัดสินใจว่าคุณจำเป็นจริงๆ NEG (ปฏิเสธการใช้ส่วนประกอบทั้งสอง) การเรียนการสอนโดยใช้ opcode นี้โดยเฉพาะเพื่อการนี้ทำให้ความรู้สึกมากเพราะคุณอาจจะคาดหวังว่าการเรียนการสอน NEG ที่จะใช้รูปแบบเดียวกัน (และดังนั้น ถอดรหัส) ในขณะที่การเรียนการสอนไม่ได้
ในทำนองเดียวกันถ้าคุณต้องการที่จะเพิ่มการเรียนการสอนศูนย์ดำเนินการชุดคำสั่งมีสามไม่ได้กำหนดคำแนะนำศูนย์ถูกดำเนินการที่คุณสามารถใช้เพื่อการนี้ คุณเพียงแค่ต้องการที่เหมาะสมหนึ่ง opcodes เหล่านี้และกำหนดคำสั่งของคุณไป
แต่น่าเสียดายที่ Y86 CPU ไม่ได้มีที่ opcodes ที่ผิดกฎหมายจำนวนมากเปิด ตัวอย่างเช่นถ้าคุณต้องการที่จะเพิ่ม SHL, SHR, ROL และคำแนะนำ ROR (เปลี่ยนและหมุนซ้ายและขวา) เป็นคำแนะนำเดียวที่ถูกดำเนินการมีพื้นที่ไม่เพียงพอในการเรียนการสอนเดียว opcodes ถูกดำเนินการเพื่อเพิ่มคำแนะนำเหล่านี้ (มีอยู่ในขณะนี้ เพียงหนึ่ง opcode เปิดคุณสามารถใช้) ในทำนองเดียวกันไม่มี opcodes สองตัวถูกดำเนิน-เปิดดังนั้นหากคุณต้องการที่จะเพิ่มการเรียนการสอนแฮคเกอร์หรืออื่น ๆ การเรียนการสอนสองตัวถูกดำเนินการ, คุณจะออกจากโชค
วิธีการทั่วไปที่จะจัดการกับภาวะที่กลืนไม่เข้าคายไม่ออกนี้ (หนึ่งในนักออกแบบที่มีการจ้างงาน Intel) คือการใช้คำนำหน้าไบต์ opcode นี้รูปแบบการขยายตัว opcode ใช้หนึ่งใน opcodes ไม่ได้กำหนดเป็นคำนำหน้าไบต์ opcode เมื่อใดก็ตามที่ซีพียูพบไบต์คำนำหน้าในหน่วยความจำก็อ่านและถอดรหัสไบต์ต่อไปในหน่วยความจำ opcode ที่เกิดขึ้นจริง แต่ก็ไม่ได้รักษานี้ไบต์ที่สองเป็นมันจะ opcode อื่น ๆ แต่นี้ไบต์ opcode ที่สองใช้รูปแบบการเข้ารหัสที่แตกต่างกันอย่างสมบูรณ์และจึงช่วยให้คุณสามารถระบุคำสั่งใหม่มากเท่าที่คุณสามารถเข้ารหัสในไบต์ (หรือไบต์ถ้าคุณชอบ) ตัวอย่างเช่น opcode $ FF เป็นเรื่องผิดกฎหมาย (มันสอดคล้องกับ "MOV (DX, const);" การเรียนการสอน) เพื่อให้เราสามารถใช้ไบต์เป็นไบต์คำนำหน้าพิเศษที่จะขยายเพิ่มเติมชุดคำสั่ง
11 .
รูปที่ 13 การใช้คำนำหน้าไบต์ที่จะขยายชุดคำสั่ง
4 การเข้ารหัสคำแนะนำ 80x86
Y86 ประมวลผลที่ง่ายต่อการเข้าใจและง่ายต่อการใช้การเข้ารหัสมือสำหรับมันและยานพาหนะที่ดีสำหรับการเรียนรู้วิธีการกำหนด opcodes นอกจากนี้ยังเป็นอุปกรณ์สมมุติอย่างหมดจดมุ่งหวังให้ใช้เป็นเครื่องมือในการเรียนการสอนดังนั้นตอนนี้คุณสามารถลืมทั้งหมดเกี่ยวกับ Y86 ก็ทำหน้าที่จุดประสงค์ของมัน ตอนนี้ก็ถึงเวลาที่จะดูว่ารูปแบบการเรียนการสอนเครื่องที่เกิดขึ้นจริงสำหรับครอบครัว CPU 80x86
พวกเขาไม่ได้เรียก CPU 80x86
คอมเพล็กซ์ชุดคำสั่งคอมพิวเตอร์เพื่ออะไร ถึงแม้ว่าการเรียนการสอนมากขึ้นการเข้ารหัสที่ซับซ้อนไม่อยู่ไม่มีใครจะที่จะท้าทายการยืนยันว่า 80x86 มีการเข้ารหัสการเรียนการสอนที่มีความซับซ้อน การเรียนการสอน 80x86 ทั่วไปใช้รูปแบบที่แสดงใน
รูปที่ 5.14 . แม้ว่าแผนภาพนี้ดูเหมือนว่าจะหมายความว่าคำแนะนำจะขึ้นอยู่กับ 16 ไบต์นานในความเป็นจริง 80x86 จะไม่อนุญาตให้คำแนะนำมากกว่า 15 ไบต์ในระยะเวลา
รูปที่ 5.14 80x86 การเรียนการสอนการเข้ารหัส
ไบต์คำนำหน้าไม่ได้ "คำนำหน้าการขยายตัว opcode" ที่ส่วนก่อนหน้านี้ในบทนี้กล่าวถึง แต่เหล่านี้เป็นไบต์พิเศษในการปรับเปลี่ยนพฤติกรรมของคำสั่งที่มีอยู่ (แทนที่จะกำหนดคำสั่งใหม่) เราจะมาดูที่คู่ของไบต์คำนำหน้าเหล่านี้ในนิด ๆ หน่อย ๆ คนอื่น ๆ ที่เราจะออกจากการอภิปรายในบทต่อ 80x86 แน่นอนสนับสนุนมากกว่าสี่ค่าคำนำหน้า แต่การเรียนการสอนอาจมีได้สูงสุดสี่คำนำหน้าไบต์ที่ติดอยู่กับมัน ยังทราบว่าพฤติกรรมของไบต์คำนำหน้ามากเป็นพิเศษร่วมกันและผลลัพธ์ที่ไม่ได้กำหนดถ้าคุณใส่คู่ของไบต์คำนำหน้าพิเศษร่วมกันในหน้าของการเรียนการสอน
80x86 สนับสนุนสองขนาด opcode พื้นฐาน opcode มาตรฐานหนึ่งไบต์และ opcode สองไบต์ซึ่งประกอบด้วย $ 0F ขยาย opcode คำนำหน้าไบต์และไบต์ที่สองระบุการเรียนการสอนที่เกิดขึ้นจริง วิธีหนึ่งที่จะดูไบ opcode เหล่านี้เป็นส่วนขยายแปดบิตของ
คข้อมูลในการเข้ารหัส Y86 นี้ให้ได้ถึง 512 การเรียนการสอนที่แตกต่างกัน (แม้ว่า 80x86 ยังไม่ใช้พวกเขาทั้งหมด) ในความเป็นจริงการเรียนการสอนที่แตกต่างกันใช้บิตบางอย่างใน opcode นี้สำหรับวัตถุประสงค์เด็ดที่ไม่ได้การเรียนการสอนชั้น ตัวอย่างเช่นพิจารณา opcode คําสั่ง ADD มันต้องใช้รูปแบบที่แสดงใน
รูปที่ 5.15 .
หมายเหตุจำนวนบิตที่ศูนย์ระบุขนาดของตัวถูกดำเนินการเรียนการสอนเพิ่มการดำเนินงานตาม ถ้าฟิลด์นี้มีศูนย์แล้วตัวถูกดำเนินการเป็นแปดบิตลงทะเบียนและสถานที่หน่วยความจำ ถ้าบิตนี้มีหนึ่งตัวถูกดำเนินการแล้วมีทั้ง 16 บิตหรือ 32 บิต ภายใต้ระบบปฏิบัติการแบบ 32 บิตเริ่มต้นคือตัวถูกดำเนินการ 32 บิตถ้าฟิลด์นี้มีหนึ่ง เพื่อระบุตัวถูกดำเนินการ 16 บิต (ภายใต้ Windows หรือ Linux) คุณต้องแทรกพิเศษ "ถูกดำเนินการขนาดคำนำหน้าไบต์" ในหน้าของการเรียนการสอน
จำนวนบิตหนึ่งระบุทิศทางของการถ่ายโอน ถ้าบิตนี้เป็นศูนย์แล้วถูกดำเนินการปลายทางเป็นที่ตั้งของหน่วยความจำ (เช่น "เพิ่ม (อัล [ebx]);" ถ้าบิตนี้เป็นหนึ่งในนั้นถูกดำเนินการปลายทางคือการลงทะเบียน (เช่น "เพิ่ม ([ebx] อัล); "เร็ว ๆ นี้จะเห็นว่าบิตทิศทางนี้สร้างปัญหาที่ส่งผลให้การเรียนการสอนหนึ่งมีสอง opcodes เป็นไปได้ที่แตกต่างกัน
รูปที่ 5.15 80x86 ADD Opcode
4.1 การเข้ารหัสตัวถูกดำเนินการเรียนการสอน
"MOD-reg-R / เมตร" ไบต์ (ใน
รูปที่ 14 ) ระบุโหมดพื้นฐาน ไบต์นี้มีฟิลด์ต่อไปนี้
รูปที่ 5.16 MOD-รุ่น-R / M Byte
ข้อมูลราคาพิเศษระบุ 80x86 ลงทะเบียน ทั้งนี้ขึ้นอยู่กับการเรียนการสอนนี้สามารถเป็นได้ทั้งแหล่งที่มาหรือถูกดำเนินการปลายทาง คำแนะนำหลายคนมี "D" (ทิศทาง) ในสนาม opcode ของพวกเขาที่จะเลือกได้ว่าจะถูกดำเนินการนี้เป็นแหล่งที่มา (d = 0) หรือปลายทาง (d = 1) ตัวถูกดำเนินการข้อมูลนี้จะถูกเข้ารหัสโดยใช้รูปแบบบิตที่พบในตารางต่อไปนี้
ราคาพิเศษมูลค่า
|
ลงทะเบียนถ้าขนาดของข้อมูลเป็นแปดบิต
|
ลงทะเบียนถ้าขนาดของข้อมูลคือ 16 บิต
|
ลงทะเบียนถ้าขนาดของข้อมูล 32 บิต
|
000%
|
อัล
|
ขวาน
|
EAX
|
001%
|
CL
|
CX
|
ECX
|
010%
|
ดล
|
DX
|
EDX
|
011%
|
BL
|
BX
|
ebx
|
100%
|
อา
|
SP
|
ทาย
|
101%
|
CH
|
bp
|
EBP
|
110%
|
DH
|
si
|
ESI
|
111%
|
BH
|
ดิ
|
EDI
|
สำหรับบาง (ตัวถูกดำเนินการเดี่ยว) คำแนะนำด้านราคาอาจจะมีการขยาย opcode มากกว่าค่าลงทะเบียน (ข้อมูล R / M จะระบุตัวถูกดำเนินการในกรณีนี้)
MOD และ R / M สาขารวมกันเพื่อระบุตัวถูกดำเนินการอื่น ๆ ในการเรียนการสอนสองตัวถูกดำเนินการ (หรือถูกดำเนินการเฉพาะในการเรียนการสอนเดี่ยวถูกดำเนินการเหมือนหรือไม่ NEG) โปรดจำไว้ว่าบิต "D" ใน opcode กำหนดตัวถูกดำเนินการเป็นแหล่งที่มาและที่เป็นสถานที่ MOD และ R / M สาขาที่ร่วมกันระบุโหมดที่อยู่ดังต่อไปนี้
MOD
|
ความหมาย
|
00%
|
ลงทะเบียนโหมดทางอ้อมหรือ SIB ที่ไม่มีการเคลื่อนที่ (เมื่อ R / M = 100%) หรือแทนที่เท่านั้นที่อยู่โหมด (เมื่อ R / M = 101%)
|
01%
|
หนึ่งไบต์ลงนามในการกำจัดต่อไปนี้ที่อยู่โหมดไบต์ (s)
|
10%
|
สี่ไบต์ลงนามในการกำจัดต่อไปนี้ที่อยู่โหมดไบต์ (s)
|
11%
|
โหมดสมัครสมาชิก
|
MOD
|
R / M
|
โหมดที่อยู่
|
00%
|
000%
|
[EAX]
|
01%
|
000%
|
[EAX + DISP 8 ]
|
10%
|
000%
|
[EAX + DISP 32 ]
|
11%
|
000%
|
ลงทะเบียน (อัล / ขวาน / EAX) 1
|
00%
|
001%
|
[ECX]
|
01%
|
001%
|
[ECX + DISP 8 ]
|
10%
|
001%
|
[ECX + DISP 32 ]
|
11%
|
001%
|
ลงทะเบียน (CL / CX / ECX)
|
00%
|
010%
|
[EDX]
|
01%
|
010%
|
[EDX + DISP 8 ]
|
10%
|
010%
|
[EDX + DISP 32 ]
|
11%
|
010%
|
ลงทะเบียน (DL / DX / EDX)
|
00%
|
011%
|
[ebx]
|
01%
|
011%
|
[ebx + DISP 8 ]
|
10%
|
011%
|
[ebx + DISP 32 ]
|
11%
|
011%
|
ลงทะเบียน (BL / BX / ebx)
|
00%
|
100%
|
โหมด SIB
|
01%
|
100%
|
SIB + DISP 8โหมด
|
10%
|
100%
|
SIB + DISP 32โหมด
|
11%
|
100%
|
ลงทะเบียน (อา / SP / ESP)
|
00%
|
101%
|
แทนที่โหมดเท่านั้น
(ราง 32 บิต)
|
01%
|
101%
|
[EBP + DISP 8 ]
|
10%
|
101%
|
[EBP + DISP 32 ]
|
11%
|
101%
|
ลงทะเบียน (CH / bp / EBP)
|
00%
|
110%
|
[ESI]
|
01%
|
110%
|
[ESI + DISP 8 ]
|
10%
|
110%
|
[ESI + DISP 32 ]
|
11%
|
110%
|
ลงทะเบียน (DH / si / ESI)
|
00%
|
111%
|
[EDI]
|
01%
|
111%
|
[EDI + DISP 8 ]
|
10%
|
111%
|
[EDI + DISP 32 ]
|
11%
|
111%
|
ลงทะเบียน (BH / DI / EDI)
|
1บิตขนาดใน opcode ระบุขนาดลงทะเบียนแปดหรือ 32 บิต ในการเลือกลงทะเบียน 16 บิตต้องใช้คำนำหน้าไบต์
|
มีสองสิ่งที่น่าสนใจที่จะต้องทราบเกี่ยวกับตารางนี้ แรกของทั้งหมดทราบว่ามีสองรูปแบบของ [reg + DISP] โหมดที่อยู่: รูปแบบหนึ่งที่มีการเคลื่อนที่แปดบิตและรูปแบบหนึ่งที่มีการเคลื่อนที่ 32 บิต ที่อยู่ในโหมดที่มีการเคลื่อนที่อยู่ในช่วง -128 .. 127 + ต้องการเพียงรางไบต์เดี่ยวหลังจาก opcode;ด้วยเหตุนี้คำแนะนำเหล่านี้จะสั้นลง (และบางครั้งได้เร็วกว่า) คำแนะนำการกำจัดที่มีค่าอยู่นอกช่วงนี้ แต่กลับกลายเป็นว่าชดเชยจำนวนมากในช่วงนี้เพื่อให้ผู้ประกอบ / คอมไพเลอร์สามารถสร้างคำแนะนำสั้นสำหรับใหญ่ร้อยละของคำแนะนำ
สิ่งที่สองที่ควรทราบก็คือว่าไม่มี [EBP] โหมด ถ้าคุณดูในตารางข้างต้นที่โหมดนี้เป็นเหตุผลที่คุณจะพบว่ามันเป็นช่องที่ถูกครอบครองโดยการกำจัด 32 บิตเท่านั้นโหมด รูปแบบการเข้ารหัสขั้นพื้นฐานสำหรับโหมดการอยู่ไม่ได้อนุญาตให้มีการเคลื่อนที่เฉพาะโหมดดังนั้น Intel "ขโมย" การเข้ารหัสสำหรับ [EBP] และใช้สำหรับการกำจัดโหมดเท่านั้น โชคดีที่สิ่งที่คุณสามารถทำอะไรกับ [EBP] ที่อยู่ในโหมดที่คุณสามารถทำได้ด้วย [EBP + DISP
8 ] โหมดโดยการตั้งค่าการเคลื่อนที่แปดบิตให้เป็นศูนย์ ความจริงการเรียนการสอนที่มีนิด ๆ หน่อย ๆ อีกต่อไป แต่ความสามารถยังคงมี Intel (อย่างชาญฉลาด) เลือกที่จะเปลี่ยนโหมดนี้เพราะพวกเขาคาดว่าการเขียนโปรแกรมจะใช้โหมดนี้มักจะน้อยกว่าที่อื่น ๆ ลงทะเบียนโหมดที่อยู่ทางอ้อม (ด้วยเหตุผลที่คุณจะค้นพบในบทต่อมา)
สิ่งที่คุณจะสังเกตเห็นหายไปจากโต๊ะนี้ก็จะอยู่ในรูปแบบของรูปแบบ [ebx + EDX * 4] ที่เรียกว่าปรับโหมดการจัดทำดัชนีที่อยู่ นอกจากนี้คุณยังจะสังเกตเห็นว่าตารางจะหายไปอยู่ในรูปแบบของรูปแบบ [ESP], [ESP + disp
8 ] และ [ESP + disp
32 ] ในช่องที่คุณมักจะคาดหวังกับโหมดเหล่านี้คุณจะได้พบกับ SIB (ไบต์ดัชนีปรับ) โหมดการ ถ้าค่าเหล่านี้ปรากฏอยู่ในเขต MOD และ R / M แล้วโหมดคือโหมดการจัดทำดัชนีปรับด้วยไบต์ที่สอง (ไบต์ SIB) ดังต่อไปนี้ไบต์ / M MOD-รุ่น-R ที่ระบุการลงทะเบียนการใช้งาน (หมายเหตุว่า ฟิลด์ MOD ยังระบุขนาดการกำจัดของศูนย์หนึ่งหรือสี่ bytes) แผนภาพต่อไปนี้แสดงให้เห็นถึงรูปแบบของไบต์ SIB นี้และตารางต่อไปนี้อธิบายค่าสำหรับแต่ละสาขา
รูปที่ 5.17 SIB (Byte ดัชนีสเกล) เลย์เอาต์
ขนาดมูลค่า
|
ดัชนี * มูลค่ามาตราส่วน
|
00%
|
ดัชนี * 1
|
01%
|
ดัชนี * 2
|
10%
|
ดัชนี * 4
|
11%
|
ดัชนี * 8
|
ดัชนี
|
สมัครสมาชิก
|
000%
|
EAX
|
001%
|
ECX
|
010%
|
EDX
|
011%
|
EBX
|
100%
|
ที่ผิดกฎหมาย
|
101%
|
EBP
|
110%
|
ESI
|
111%
|
EDI
|
ฐาน
|
สมัครสมาชิก
|
000%
|
EAX
|
001%
|
ECX
|
010%
|
EDX
|
011%
|
EBX
|
100%
|
ESP
|
101%
|
แทนที่เท่านั้นถ้า MOD = 00%, EBP ถ้า MOD = 01% หรือ 10%
|
110%
|
ESI
|
111%
|
EDI
|
MOD-รุ่น-R / M และ SIB ไบต์มีความซับซ้อนและยุ่งยากคำถามเกี่ยวกับว่าไม่มี เหตุผลเหล่านี้ไบต์โหมดที่ซับซ้อนเพื่อเป็นเพราะอินเทลมาใช้ใหม่ 16 บิตที่อยู่วงจรของพวกเขาในโหมด 32 บิตที่มากกว่าเพียงแค่ละทิ้งรูปแบบ 16 บิตในโหมด 32 บิต มีเหตุผลที่ดีสำหรับฮาร์ดแวร์นี้ แต่ผลสุดท้ายเป็นโครงการที่ซับซ้อนสำหรับการระบุรูปแบบที่อยู่
ส่วนหนึ่งของเหตุผลที่โครงการที่อยู่เป็นที่ซับซ้อนเพื่อเป็นเพราะกรณีพิเศษสำหรับโหมด SIB และการกำจัดอย่างเดียว คุณจะทราบว่าการเข้ารหัสที่ใช้งานง่ายของ / M ไบต์ MOD-รุ่น-R ไม่อนุญาตให้มีโหมดการกำจัดอย่างเดียว อินเทลเพิ่ม kludge อย่างรวดเร็วเพื่อโครงการที่อยู่แทนที่ [EBP] โหมดที่มีโหมดการกำจัดอย่างเดียว โปรแกรมเมอร์ที่จริงต้องการใช้ [EBP] โหมดต้องใช้ [EBP + 0] แทน ความหมายโหมดนี้ก่อให้เกิดผลเหมือนกัน แต่การเรียนการสอนเป็นหนึ่งไบต์นานเนื่องจากต้องการไบต์รางที่มีศูนย์
นอกจากนี้คุณยังจะได้ทราบว่าหากข้อมูลราคาพิเศษของไบต์ MOD-รุ่น-R / M มี 100% และ MOD ไม่ได้มี 11% แล้วโหมดคือ "SIB โหมด" มากกว่าที่คาดว่าจะ [ESP], [ESP + DISP
8 ] หรือ [ESP + disp
32 ] โหมด โหมด SIB จะใช้เมื่อใช้โหมดหนึ่งในการลงทะเบียนการจัดทำดัชนีปรับคือหนึ่งในโหมดที่อยู่ดังต่อไปนี้
[reg
32 + EAX n *] MOD = 00%
[reg
32 + ebx n *] หมายเหตุ: n = 1, 2, 4 หรือ 8
[DISP + reg
8 + EAX n *] MOD = 01%
[DISP + reg
32 + EAX n *] MOD = 10%
[DISP + reg
32 + ebx n *]
[DISP + reg
32 + ECX n *]
[DISP + reg
32 + EDX n *]
[DISP + reg
32 + EBP n *]
[DISP + reg
32 + ESI n *]
[DISP + reg
32 + EDI n *]
[DISP + EAX n *] MOD = 00% และสนาม BASE มี 101%
ในแต่ละโหมดการแก้ไขเหล่านี้ข้อมูล MOD ของไบต์ MOD-รุ่น-R / M ระบุขนาดของราง (ศูนย์หนึ่งหรือสี่ bytes) นี้จะแสดงผ่านทางโหมด "SIB โหมด", "SIB + DISP
8โหมด "และ" SIB + DISP
32โหมด ". ฐานและดัชนีด้านการไบต์ SIB เลือกฐานและดัชนีลงทะเบียนตามลำดับ ทราบว่าโหมดนี้ไม่อนุญาตให้ใช้ในการลงทะเบียน ESP เป็นดัชนีลงทะเบียน สันนิษฐานว่าอินเทลซ้ายโหมดนี้โดยเฉพาะไม่ได้กำหนดที่จะให้ความสามารถในการขยายรูปแบบที่อยู่ในรุ่นอนาคตของ CPU (แม้ว่าการขยายลำดับโหมดสามไบต์ดูเหมือนว่าบิตมาก)
เช่นการเข้ารหัส MOD-รุ่น-R / M, รูปแบบ SIB นิยามใหม่ของโหมด [EBP + ระดับ * ดัชนี] เป็นโหมดการกำจัดบวกดัชนี อีกครั้งถ้าคุณจริงๆต้องโหมดนี้คุณจะต้องใช้ค่าไบต์เดี่ยวรางที่มีศูนย์เพื่อให้บรรลุผลเดียวกัน
4.2 การเข้ารหัสคำสั่ง ADD: ตัวอย่างบางส่วน
ที่จะคิดออกวิธีการเข้ารหัสการสอนโดยใช้รูปแบบที่ซับซ้อนนี้ตัวอย่างบางรับประกัน จึงขอใช้เวลามากในวิธีการเข้ารหัสการเรียนการสอน 80x86 ADD ใช้กับโหมดต่างๆ opcode เพิ่มเป็น $ 00 $ 01, $ 02 หรือ $ 03 ขึ้นอยู่กับทิศทางและขนาดของบิตใน opcode (ดู
รูปที่ 5.15 ) ตัวเลขต่อไปนี้แต่ละอธิบายวิธีการเข้ารหัสรูปแบบต่างๆของการเรียนการสอนเพิ่มโดยใช้โหมดที่อยู่ที่แตกต่างกัน
รูปที่18 การเข้ารหัส ADD (อัล, CL); การเรียนการสอน
มีผลข้างเคียงที่น่าสนใจของการดำเนินการของบิตทิศทางและองค์กร MOD-รุ่น-R / M คือคำแนะนำบางอย่างมีสอง opcodes แตกต่างกัน (และทั้งสองตามกฎหมาย) ตัวอย่างเช่นเราสามารถเข้ารหัส "เพิ่ม (อัล, CL);" การเรียนการสอนจาก
รูปที่ 5.18เป็น $ 02, $ C8 โดยการกลับ AL CL และลงทะเบียนในราคาพิเศษและ R / สาขา M แล้วตั้งค่า
งบิตใน opcode (บิต # 1) ปัญหานี้นำไปใช้กับคำแนะนำที่มีสองตัวถูกดำเนินการลงทะเบียน
รูปที่ 19 การเข้ารหัส ADD (EAX, ECX); การเรียนการสอน
โปรดทราบว่าเรายังสามารถเข้ารหัส "เพิ่ม (EAX, ECX);" โดยใช้ไบต์ $ 03, $ C8
รูปที่ 20 การเข้ารหัส ADD (DISP, EDX); การเรียนการสอน
รูปที่ 21 การเข้ารหัส ADD ([ebx] EDI); การเรียนการสอน
รูปที่ 22 การเข้ารหัส ADD ([ESI + DISP
8 ], EAX); การเรียนการสอน
รูปที่ 23 การเข้ารหัส ADD ([EBP + DISP
32 ], ebx); การเรียนการสอน
รูปที่ 24 การเข้ารหัส ADD ([DISP
32 + EAX * 1], EBP); การเรียนการสอน
รูปที่ 5.25 การเข้ารหัส ADD ([ebx + EDI * 4], ECX); การเรียนการสอน
4.3 การเข้ารหัสตัวถูกดำเนินการทันที
คุณอาจสังเกตเห็นว่า MOD-REG-R / M และ SIB ไบต์ไม่ได้มีการรวมบิตใด ๆ ที่คุณสามารถใช้เพื่อระบุตัวถูกดำเนินการทันที 80x86 ใช้ opcode ที่แตกต่างกันอย่างสิ้นเชิงในการระบุตัวถูกดำเนินการทันที
ภาพที่ 5.26แสดงให้เห็นถึงการเข้ารหัสขั้นพื้นฐานสำหรับการเพิ่มการเรียนการสอนได้ทันที
รูปที่ 5.26 การเข้ารหัสเพิ่มการเรียนการสอนทันที
มีสามความแตกต่างที่สำคัญระหว่างการเข้ารหัสของการเพิ่มทันทีและคําสั่ง ADD มาตรฐาน ครั้งแรกและที่สำคัญที่สุด opcode มีหนึ่งในตำแหน่งบิต HOนี้จะบอก CPU ที่การเรียนการสอนที่มีอย่างต่อเนื่องได้ทันที การเปลี่ยนแปลงนี้แต่ละคน แต่ไม่ได้บอก CPU ที่จะต้องดำเนินการเรียนการสอนเพิ่มในขณะที่คุณจะเห็นชั่วขณะ
ความแตกต่างที่สองคือว่าไม่มีทิศทางบิตใน opcode นี้ทำให้รู้สึกเพราะคุณไม่สามารถระบุตัวถูกดำเนินการอย่างต่อเนื่องเป็นหัวข้อ ดังนั้นตัวถูกดำเนินการปลายทางอยู่เสมอสถานที่ MOD และ R / M บิตระบุในฟิลด์ MOD-REG-R / M
ในสถานที่ของบิตทิศทาง opcode มีนามสกุลสัญญาณ (
x ) บิต สำหรับตัวถูกดำเนินการแปดบิตซีพียูละเว้นบิตนี้ สำหรับ 16 บิตและ 32 บิตถูกดำเนินการบิตนี้ระบุขนาดของค่าคงที่ดังต่อไปนี้การเรียนการสอนเพิ่ม ถ้าบิตนี้มีศูนย์แล้วคงเป็นขนาดเดียวกับตัวถูกดำเนินการ (เช่น 16 หรือ 32 บิต) ถ้าบิตนี้มีหนึ่งในนั้นคงเป็นค่าแปดบิตลงนามและเข้าสู่ระบบ CPU ขยายค่านี้เป็นขนาดที่เหมาะสมก่อนที่จะเพิ่มตัวถูกดำเนินการ นี้เคล็ดลับเล็ก ๆ มักจะทำให้โปรแกรมค่อนข้างสั้นเพราะโดยทั่วไปคงที่จะเพิ่มมูลค่าขนาดเล็กถึง 16 หรือ 32 บิตตัวถูกดำเนินการ
ความแตกต่างระหว่างสามเพิ่มทันทีและคําสั่ง ADD มาตรฐานคือความหมายของข้อมูลราคาพิเศษในไบต์ MOD-รุ่น-R / M ตั้งแต่การเรียนการสอนที่มีความหมายที่ถูกดำเนินการมาเป็นอย่างต่อเนื่องและเขต MOD-R / M ระบุตัวถูกดำเนินการปลายทางการเรียนการสอนไม่จำเป็นต้องใช้ข้อมูลราคาพิเศษเพื่อระบุตัวถูกดำเนินการ แต่ 80x86 CPU ใช้เหล่านี้สามบิตเป็นส่วนขยาย opcode สำหรับการเพิ่มการเรียนการสอนได้ทันทีทั้งสามชิ้นจะต้องมีศูนย์ (รูปแบบบิตอื่น ๆ ที่จะสอดคล้องกับการเรียนการสอนที่แตกต่างกัน)
ทราบว่าเมื่อมีการเพิ่มอย่างต่อเนื่องไปยังตำแหน่งหน่วยความจำ, การเคลื่อนที่ (ถ้ามี) ที่เกี่ยวข้องกับสถานที่ตั้งหน่วยความจำทันทีก่อนทันที (คงที่) ข้อมูลในลำดับ opcode
4.4 การเข้ารหัสแปดสิบหกและสามสิบสองบิตตัวถูกดำเนินการ
เมื่ออินเทลออกแบบ 8086 พวกเขาใช้หนึ่งบิต (
S ) เพื่อเลือกระหว่างแปดและสิบหกจำนวนเต็มบิตขนาดตัวถูกดำเนินการใน opcode ต่อมาเมื่อพวกเขาขยายสถาปัตยกรรม 80x86 ที่ 32 บิตด้วยการแนะนำของ 80386 ที่พวกเขามีปัญหากับบิตเดียวที่พวกเขาจะสามารถเข้ารหัสสองขนาด แต่พวกเขาจำเป็นต้องใช้การเข้ารหัสสาม (8, 16, และ 32 บิต) เพื่อแก้ปัญหานี้พวกเขาใช้
คำนำหน้าตัวถูกดำเนินการขนาดไบต์ .
Intel ศึกษาการเรียนการสอนของพวกเขาตั้งค่าและมาสรุปว่าในสภาพแวดล้อมที่ 32 บิตโปรแกรมมีแนวโน้มที่จะใช้แปดบิตและ 32 บิตถูกดำเนินการไกลบ่อยกว่าตัวถูกดำเนินการ 16 บิต ดังนั้น Intel ตัดสินใจที่จะให้บิตขนาด (
S ) ใน opcode เลือกระหว่างแปดสามสิบสองตัวถูกดำเนินการบิตในขณะที่ส่วนก่อนหน้าอธิบาย แม้ว่าโปรแกรม 32 บิตที่ทันสมัยไม่ใช้ตัวถูกดำเนินการ 16 บิตที่มักจะพวกเขาไม่ต้องการพวกเขาตอนนี้แล้ว เพื่อให้สามารถถูกดำเนินการ 16 บิตของอินเทลช่วยให้คุณคำนำหน้าคำสั่ง 32 บิตกับไบต์คำนำหน้าขนาดตัวถูกดำเนินการค่าซึ่งเป็น $ 66 ไบต์คำนำหน้านี้จะบอก CPU ที่ถูกดำเนินการกับข้อมูลที่ 16 บิตมากกว่าข้อมูล 32 บิต
คุณไม่ได้อย่างชัดเจนใส่คำนำหน้าไบต์ขนาดตัวถูกดำเนินการในด้านหน้าของคำแนะนำของคุณ 16 บิต; แอสเซมจะดูแลเรื่องนี้ให้คุณโดยอัตโนมัติเมื่อคุณใช้ตัวถูกดำเนินการ 16 บิตในการเรียนการสอน แต่ทำเก็บไว้ในใจว่าเมื่อใดก็ตามที่คุณใช้ตัวถูกดำเนินการ 16 บิตในโปรแกรม 32 บิต, การเรียนการสอนมีความยาว (โดยหนึ่งไบต์) เพราะค่าคำนำหน้า ดังนั้นคุณควรจะระมัดระวังเกี่ยวกับการใช้คำแนะนำ 16 บิตถ้าขนาด (และบอช, ความเร็ว) มีความสำคัญเพราะคำแนะนำเหล่านี้จะมีความยาว (และอาจจะช้าลงเพราะผลของพวกเขาในแคช)
4.5 การเข้ารหัสอื่นสำหรับคำแนะนำ
ดังที่ระบุไว้ก่อนหน้านี้ในบทนี้ซึ่งเป็นหนึ่งในเป้าหมายในการออกแบบของอินเทลหลักสำหรับ 80x86 คือการสร้างชุดคำสั่งเพื่อให้การเขียนโปรแกรมเพื่อเขียนโปรแกรมที่สั้นมากเพื่อประหยัดค่า (ในเวลานั้น) หน่วยความจำ วิธีการหนึ่งที่พวกเขาทำอย่างนี้คือการสร้างการเข้ารหัสอื่นของบางคำแนะนำที่ใช้กันมาก คำแนะนำเหล่านี้เป็นทางเลือกที่สั้นกว่าคู่มาตรฐานและ Intel หวังว่าการเขียนโปรแกรมที่จะทำให้การใช้งานที่กว้างขวางของคำแนะนำเหล่านี้ดังนั้นการสร้างโปรแกรมที่สั้นกว่า
ตัวอย่างที่ดีของคำแนะนำเหล่านี้เป็นทางเลือก "เพิ่ม (คงที่สะสม);" คำแนะนำ (สะสมเป็น AL, ขวานหรือ EAX) 80x86 ให้ opcode เดียวไบต์สำหรับ "เพิ่ม (คงที่อัล);" และ "เพิ่ม (คงที่ EAX);" (opcodes เป็น $ 04 และ $ 05 ตามลำดับ) กับ opcode หนึ่งไบต์และไม่มีไบต์ MOD-REG-R / M, คำแนะนำเหล่านี้เป็นหนึ่งในไบต์สั้นกว่ามาตรฐานของพวกเขาใส่คู่ทันที ทราบว่า "เพิ่ม (คงขวาน);" การเรียนการสอนต้องมีคำนำหน้าขนาดตัวถูกดำเนินการ (เช่นเดียวกับมาตรฐาน "เพิ่ม (คงขวาน);" การเรียนการสอนจึงเป็น opcode มีประสิทธิภาพสองไบต์ถ้าคุณนับไบต์คำนำหน้านี้ แต่ยังคงเป็นหนึ่งไบต์สั้นกว่าการเพิ่มมาตรฐานสอดคล้อง. ทันที
คุณไม่ได้มีการระบุอะไรเป็นพิเศษที่จะใช้คำแนะนำเหล่านี้ ๆ ประกอบที่ดีโดยอัตโนมัติจะเลือกการเรียนการสอนที่สั้นที่สุดที่จะสามารถใช้เมื่อแปลรหัสต้นฉบับของคุณเป็นรหัสเครื่อง อย่างไรก็ตามคุณควรทราบว่าอินเทลจะให้การเข้ารหัสสำรองสำหรับการลงทะเบียนสะสม ดังนั้นถ้าคุณมีทางเลือกของหลายคำแนะนำในการใช้และการลงทะเบียนสะสมอยู่ในตัวเลือกเหล่านี้ AL / ขวาน / EAX registers มักจะให้ทางออกที่ดีที่สุด นี่คือเหตุผลว่าทำไมคุณควรใช้เวลาในการสแกนผ่านการเข้ารหัสของคำสั่ง 80x86 บางเวลา โดยทำความคุ้นเคยกับการเข้ารหัสการเรียนการสอนที่คุณจะได้รู้ว่าที่มีคำแนะนำพิเศษ (และดังนั้นสั้น) การเข้ารหัส
5 วางมันทั้งหมดเข้าด้วยกัน
การออกแบบชุดคำสั่งที่สามารถยืนการทดสอบของเวลาเป็นความท้าทายทางปัญญาที่แท้จริง วิศวกรจะต้องสมดุลหลายประนีประนอมเมื่อเลือกชุดคำสั่งและกำหนด opcodes สำหรับคำแนะนำ ชุดคำสั่ง 80x86 Intel เป็นตัวอย่างที่คลาสสิกของ kludge ที่ผู้คนกำลังใช้เพื่อวัตถุประสงค์ในการออกแบบเดิมไม่เคยตั้งใจ อย่างไรก็ตาม 80x86 ยังเป็นบทพิสูจน์ที่ยิ่งใหญ่ให้กับความฉลาดของวิศวกรของอินเทลที่ถูกต้องเผชิญกับงานที่ยากของการขยาย CPU ในรูปแบบมันก็ไม่เคยตั้งใจ ผลลัพธ์ที่ได้ แต่การทำงานมีความซับซ้อนมาก เห็นได้ชัดว่าหนึ่งในการออกแบบซีพียู (ตั้งแต่เริ่มต้น) วันนี้จะเลือกการเข้ารหัสที่วิศวกรของอินเทลกำลังใช้ อย่างไรก็ตาม 80x86 CPU ไม่แสดงให้เห็นว่าการวางแผนอย่างระมัดระวัง (หรือโชคธรรมดาเพียง) จะให้นักออกแบบสามารถในการขยาย CPU ไกลเกินกว่าการออกแบบที่เป็นต้นฉบับ
ประวัติศาสตร์ความเป็นจริงสิ่งสำคัญที่เราได้เรียนรู้จากครอบครัว 80x86 เป็นว่ามันเป็นวางแผนไม่ดีมากที่จะคิดว่า CPU ของคุณจะมีอายุเพียงช่วงเวลาสั้น ๆ และว่าผู้ใช้จะเปลี่ยนชิปและซอฟแวร์ของพวกเขาเมื่อสิ่งที่ดีกว่ามาพร้อม นักพัฒนาซอฟต์แวร์มักจะไม่ได้มีปัญหาปรับตัวเข้ากับสถาปัตยกรรมใหม่เมื่อพวกเขาเขียนซอฟต์แวร์ใหม่ (สมมติว่าแรงจูงใจทางการเงินที่จะทำเช่นนั้น) แต่พวกเขามีความทนทานมากที่จะย้ายซอฟต์แวร์ที่มีอยู่จากแพลตฟอร์มหนึ่งไปยังอีก นี่คือเหตุผลหลัก 80x86 แพลตฟอร์มอินเทลยังคงได้รับความนิยมมาจนถึงทุกวันนี้
คำแนะนำการเลือกที่คุณต้องการที่จะรวมเข้าไปในการออกแบบเบื้องต้นของซีพียูใหม่เป็นงานที่ยาก คุณต้องรักษาความสมดุลของความปรารถนาที่จะให้มีจำนวนมากคำแนะนำที่เป็นประโยชน์กับงบประมาณของซิลิกอนและคุณยังจะต้องระมัดระวังไม่ให้มีจำนวนมากของคำสั่งที่ไม่เกี่ยวข้องว่าโปรแกรมเมอร์ลมขึ้นไม่สนใจสำหรับหนึ่งหรือเหตุผลอื่น โปรดจำไว้ว่ารุ่นอนาคตทั้งหมดของซีพียูอาจจะมีคำแนะนำให้การสนับสนุนทั้งหมดที่อยู่ในชุดคำสั่งเริ่มต้นดังนั้นจึงดีกว่าที่จะผิดพลาดในด้านของการจัดส่งคำแนะนำน้อยเกินไปมากกว่ามากเกินไป จำไว้ว่าคุณสามารถขยายชุดการเรียนการสอนในรุ่นที่ใหม่กว่าของชิป
จับมือกับการเลือกชุดคำสั่งที่เหมาะสมจะช่วยให้การขยายตัวในอนาคตได้ง่ายของชิป
คุณต้องออกบางส่วนที่ไม่ได้กำหนด opcodes ใช้ได้เพื่อให้คุณสามารถขยายการเรียนการสอนที่กำหนดในภายหลัง อย่างไรก็ตามคุณต้องรักษาความสมดุลของจำนวน opcodes ไม่ได้กำหนดที่มีจำนวนของคำแนะนำเริ่มต้นและขนาดของ opcodes ของคุณ สำหรับเหตุผลที่มีประสิทธิภาพที่เราต้องการ opcodes ที่จะสั้นที่สุดเท่าที่เป็นไปได้ นอกจากนี้เรายังต้องมีชุดที่เหมาะสมของคำสั่งในชุดคำสั่งเริ่มต้น ชุดคำสั่งที่เหมาะสมอาจใช้มากที่สุดของรูปแบบบิตทางกฎหมายใน opcode ขนาดเล็ก ดังนั้นการตัดสินใจที่ยากที่จะต้องมีการทำ. ลดจำนวนของคำแนะนำในชุดคำสั่งเริ่มต้นเพิ่มขนาดของ opcode หรือพึ่งพาไบต์คำนำหน้า opcode (ซึ่งทำให้คำแนะนำใหม่ (คุณเพิ่มภายหลัง) อีกต่อไปไม่มีเป็น คำตอบที่ง่ายที่จะแก้ไขปัญหานี้เป็นนักออกแบบซีพียูที่คุณจะต้องระมัดระวังชั่งน้ำหนักทางเลือกเหล่านี้ในระหว่างการออกแบบซีพียูเริ่มต้น. แต่คุณไม่สามารถเปลี่ยนความคิดของคุณในภายหลัง
ซีพียูมากที่สุด (ฟอนนอยมันน์สถาปัตยกรรม) ใช้การเข้ารหัสไบนารีของคำสั่งและเรียกคำแนะนำเหล่านี้จากหน่วยความจำ บทนี้จะแนะนำแนวคิดของการเรียนการสอนการเข้ารหัสไบนารีผ่านสมมุติ "Y86" ประมวลผล นี้เป็นที่น่ารำคาญ (และไม่ได้ในทางปฏิบัติมาก) การออกแบบซีพียูที่ทำให้มันง่ายที่จะแสดงให้เห็นถึงวิธีการเลือก opcodes สำหรับชุดคำสั่งง่ายๆตัวถูกดำเนินการเข้ารหัสและออกจากห้องพักสำหรับการขยายตัวในอนาคต คุณลักษณะบางอย่างที่น่าสนใจมากขึ้น Y86 แสดงให้เห็นถึงความจริงที่ว่า opcode มักจะมีฟิลด์และเรามักจะแนะนำกลุ่มด้วยจำนวนของประเภทของตัวถูกดำเนินการที่พวกเขาสนับสนุน
การเข้ารหัส Y86 ยังแสดงให้เห็นถึงวิธีการใช้ opcodes พิเศษเพื่อแยกความแตกต่างกลุ่มหนึ่งของคำแนะนำจากที่อื่นและเพื่อให้ไม่ได้กำหนด (ผิดกฎหมาย) opcodes ที่เราสามารถใช้สำหรับการขยายตัวในอนาคต
Y86 CPU หมดจดสมมุติและมีประโยชน์เพียง แต่เป็นเครื่องมือการศึกษา หลังจากการสำรวจออกแบบการเรียนการสอนที่เรียบง่ายชุด Y86, บทนี้เริ่มที่จะหารือเกี่ยวกับการเข้ารหัสของคำแนะนำบนแพลตฟอร์ม 80x86 ในขณะที่ชุดคำสั่ง 80x86 เต็มอยู่ไกลที่ซับซ้อนเกินกว่าที่จะปรึกษาเรื่องนี้ในช่วงต้นของข้อความนี้ (กล่าวคือมีจำนวนมากของคำสั่งที่เรายังคงต้องหารือในภายหลังในข้อความนี้) บทนี้ก็สามารถที่จะหารือเกี่ยวกับการเข้ารหัสการเรียนการสอนขั้นพื้นฐานโดยใช้การเรียนการสอนเพิ่มเป็น ตัวอย่างเช่น ทราบว่าบทนี้เพียงสัมผัสกับรูปแบบการเข้ารหัส 80x86 การเรียนการสอน สำหรับการอภิปรายเต็มรูปแบบของการเข้ารหัส 80x86 ดูภาคผนวกในข้อความนี้และเอกสาร 80x86 อินเทล
1ในขณะที่ "ทุกอย่างรวมทั้งอ่างครัว".
2ไม่พูดถึงได้เร็วขึ้นและราคาไม่แพง
3ในการออกแบบซีพียูจำนวนมากก็ไม่ได้; แต่ตั้งแต่นี้เป็นเป้าหมายการออกแบบสำหรับ 8086 เราจะทำตามเส้นทางนี้
4สมมติว่าการดำเนินการนี้ปฏิบัติตัวถูกดำเนินการเดียวที่เป็นทั้งต้นทางและปลายทางถูกดำเนินการเป็นวิธีการทั่วไปของการจัดการเรียนการสอนนี้
5อันที่จริง Intel อ้างว่ามันเป็น opcode หนึ่งไบต์บวกหนึ่งไบต์ "MOD-reg-R / เมตร" ไบต์ สำหรับวัตถุประสงค์ของเราเราจะรักษา MOD-reg-R / เมตรไบต์เป็นส่วนหนึ่งของ opcode
6หน่วยประมวลผล Y86 เพียง แต่ดำเนินการ
ลงนามการเปรียบเทียบ
7เทคนิคการลงทะเบียนไม่ได้มีอยู่ แต่เราใช้คำว่า
โหมดที่จะลงทะเบียนอย่างไรก็ตาม
8ทั้งหมดคงเป็นตัวเลขในภาษาประกอบ Y86 จะได้รับในฐานสิบหก "$" คำนำหน้าไม่จำเป็น
9 "แยก" หมายความว่าจะคิดออกความหมายของคำสั่ง
10โปรแกรมนี้เป็นลายลักษณ์อักษรกับของ Borland Delphi และไม่ได้แจ้งความกับลินุกซ์โดยเวลานี้ถูกเขียนขึ้น
11เราอาจจะได้ใช้ค่า $ F7, $ EF และ $ E7 ตั้งแต่พวกเขายังสอดคล้องกับความพยายามในการจัดเก็บลงทะเบียนเป็นค่าคงที่ อย่างไรก็ตาม $ FF จะง่ายต่อการถอดรหัส ในทางตรงกันข้ามถ้าคุณต้องการแม้ไบต์คำนำหน้ามากขึ้นสำหรับการขยายตัวของการเรียนการสอนที่คุณสามารถใช้เหล่านี้สามค่าเช่นกัน