Assembler 8086 8088 วาดรูปทรงวงรีอย่างง่าย การสร้างกราฟิกเบื้องต้นในแอสเซมเบลอร์ เริ่มต้น

ภาษาประกอบไมโครโปรเซสเซอร์ 8088

ภาษาแอสเซมบลีเป็นภาษาเครื่องที่เขียนในรูปแบบสัญลักษณ์ ในขณะที่ที่อยู่และคำแนะนำในภาษาเครื่องเป็นตัวเลข ภาษาแอสเซมบลีอนุญาตให้กำหนดชื่อตัวอักษรที่ไม่ซ้ำกับที่อยู่หน่วยความจำ ดังนั้นเนื่องจากหน่วยปฏิบัติการของไมโครโปรเซสเซอร์ 8086 และ 8088 เหมือนกัน ภาษาแอสเซมบลี 8088 จึงกลายเป็นเหมือนกับภาษาแอสเซมบลี 8086 และเป็นส่วนหนึ่งของภาษาแอสเซมบลีของไมโครโปรเซสเซอร์ 80186 และ 80286 ซึ่งปรับปรุงการดัดแปลงของซีพียู 8086 .

โปรแกรมที่เขียนด้วยภาษาแอสเซมบลี 8088 สามารถแปล (แปล) เป็นภาษาเครื่องได้โดยใช้โปรแกรมที่เรียกว่า ผู้ประกอบ.แอสเซมเบลอร์ที่อธิบายไว้ในหนังสือเล่มนี้คือแอสเซมเบลอร์มาโครของ Microsoft ที่ใช้ใน คอมพิวเตอร์ส่วนบุคคล IBM พร้อมดิสก์ ระบบปฏิบัติการพีซี-ดอส

มีแอสเซมเบลอร์รุ่นอื่นที่ยอมรับได้สำหรับไมโครโปรเซสเซอร์ตระกูล 8086/8088 เช่นแอสเซมเบลอร์ IASM-86 ที่พัฒนาโดย Intel Corporation ซึ่ง (รวมถึงคำสั่งช่วยจำมาตรฐาน รวมถึงคำสั่งเลขคณิตสำหรับตัวเลขทศนิยมในตัวประมวลผล 8087 ความแตกต่างระหว่างแอสเซมเบลอร์เหล่านี้ โครงสร้างและรูปแบบการสอนภาษาส่วนใหญ่เข้ากันได้

ทำไมภาษาแอสเซมบลีจึงจำเป็น?

เป็นเรื่องที่ไม่สะดวก น่าเบื่อ และบางครั้งก็ยากที่จะเขียนโปรแกรมโดยตรงในภาษาเครื่อง ในเวลาเดียวกัน โปรแกรมเมอร์ต้องทำงานหนักและทำงานเป็นกิจวัตรมาก: ตรวจสอบการกระจายของเซลล์ในหน่วยความจำของไมโครคอมพิวเตอร์สำหรับการเขียนคำสั่งหรือข้อมูลโปรแกรมเพื่อให้สามารถระบุหรือกำหนดที่อยู่เหล่านี้ได้ในภายหลัง ในโปรแกรม; จำคำสั่งเครื่องจริงที่แสดงเป็นเลขฐานสองหรือเลขฐานสิบหก และวิธีการที่เกี่ยวข้องในการกำหนดที่อยู่ไมโคร


โปรเซสเซอร์; ข้อมูลทั้งหมดในโปรแกรมจะต้องถูกแปลงเป็นไบนารีเพื่อที่จะรวมไว้ในโปรแกรมภาษาเครื่อง เห็นได้ชัดว่าสามารถผิดพลาดได้หลายอย่างอันเป็นผลมาจากการทำงานดังกล่าว

ภาษาแอสเซมบลีเป็นวิธีการเขียนโปรแกรมภาษาเครื่องเชิงสัญลักษณ์ ตัวอย่างเช่น โค้ดของคำสั่งเครื่อง ZC02 (เลขฐานสิบหก) สามารถเขียนในรูปแบบสัญลักษณ์ในภาษาแอสเซมบลีเป็น CMP AL, 02 (คำสั่งนี้เปรียบเทียบเนื้อหาของรีจิสเตอร์ AL กับเลขฐานสิบหก 02) ดังนั้นการแปลงรหัสเครื่องและข้อมูลในโปรแกรมตามรายการข้างต้นจึงเป็นไปได้ เพื่อเลื่อนไปยังโปรแกรมมากที่สุด - แอสเซมเบลอร์ ดังนั้น จุดประสงค์หลักของแอสเซมเบลอร์คือการแปลโปรแกรมที่เขียนด้วยภาษาแอสเซมบลีเป็นภาษาเครื่อง (รหัสเครื่อง)

แอสเซมเบลอร์ติดตามตำแหน่งหน่วยความจำที่ใช้เพื่อให้คำแนะนำในโปรแกรมมีการอ้างอิงเชิงสัญลักษณ์ไปยังที่อยู่เหล่านี้ โดยใช้ชื่อและป้ายกำกับที่แทนที่ค่าจริง ตัวอย่างเช่น รหัสเครื่องในรูปแบบเลขฐานสิบหก C606001201 สามารถเขียนในภาษาแอสเซมบลีเป็น MOV BYTE-COUNT, 01 โดยที่ BYTE-COUNT เป็นชื่อเชิงสัญลักษณ์ของที่อยู่หน่วยความจำ 1200H

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

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

การปรับเปลี่ยนโปรแกรมภาษาแอสเซมบลีทำได้ง่ายกว่าการแก้ไขโปรแกรมที่เขียนด้วยภาษาเครื่องโดยตรง ตัวอย่างเช่น การแทรกคำสั่งสามารถเปลี่ยนแปลงได้




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

แอสเซมเบลอร์สามารถผลิตรายการ (ข้อความ) โปรแกรมเดิมซึ่งประกอบด้วยคำแนะนำภาษาแอสเซมบลีเริ่มต้น ภาษาเครื่องและรหัสข้อมูลที่เกี่ยวข้อง ผลการวินิจฉัย และ / หรือข้อความแสดงข้อผิดพลาดที่สร้างขึ้นระหว่างกระบวนการแปล ดังนั้น ข้อผิดพลาดของซอฟต์แวร์จำนวนมากสามารถตรวจพบได้ล่วงหน้าในขั้นตอนการแปล รายการโปรแกรมประกอบด้วยสัญลักษณ์ ชื่อ หรือเลเบลที่เป็นสัญลักษณ์แทนค่าคงที่หรือข้อมูลโปรแกรม รายชื่อนี้เป็นเครื่องมือที่สะดวกสำหรับการวิเคราะห์และแก้ไขข้อผิดพลาดที่อาจปรากฏขึ้นขณะดีบักโปรแกรม

รูปแบบโปรแกรม

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

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

รูปแบบทั่วไปของตัวดำเนินการ Assembler มีดังนี้:

[ป้ายกำกับ [:]] Mnemonic [ตัวดำเนินการ 1 [(, Operand2)]] [; ความคิดเห็น]

ในที่นี้ รายการในวงเล็บเหลี่ยมอาจหายไป และรายการในวงเล็บปีกกาอาจทำซ้ำได้ 1 ครั้งขึ้นไป ช่องว่างเป็นกฎเกณฑ์ แต่อย่างน้อยหนึ่งช่องว่างต้องเป็นไปตาม opcode

เลเบลเป็นตัวระบุที่เกี่ยวข้องกับแอดเดรสของไบต์แรกของโอเปอเรเตอร์ที่ปรากฏ ตัวช่วยจำเป็นตัวช่วยสำหรับคำสั่งตัวประมวลผลที่เกี่ยวข้องหรือคำสั่งแอสเซมเบลอร์ ความคิดเห็นคือลำดับของอักขระที่ขึ้นต้นด้วย ";" ต่อท้ายบรรทัดที่อธิบายคำสั่งที่เกี่ยวข้อง

เลเบลถูกใช้เป็นตัวถูกดำเนินการในคำสั่งโปรแกรมเพื่ออ้างถึงแอดเดรสของคำสั่ง (เช่น ระหว่างการข้ามแบบมีเงื่อนไขและไม่มีเงื่อนไข) และข้อมูล (เช่น ตัวแปร อาร์เรย์ โครงสร้าง) ชื่อป้ายกำกับสามารถประกอบด้วยอักขระต่อไปนี้: "A" - "Z", "a" - "z", "_", "@", "$", "?", "0" - "9" อักขระ "0" - "9" ไม่สามารถใช้เป็นอักขระตัวแรกของชื่อแท็กได้ สัญลักษณ์ "$" และ "?" มีความหมายพิเศษและไม่ควรใช้ในชื่อป้ายกำกับที่กำหนดเอง ชื่อเลเบลต้องไม่ตรงกับชื่อรีจิสเตอร์ ตัวช่วยคำสั่งตัวประมวลผล หรือคีย์เวิร์ดของแอสเซมเบลอร์ (ตัวแปรบิวท์อิน การดำเนินการ คำสั่ง)

ต้องกำหนดป้ายกำกับแต่ละรายการเพียงครั้งเดียว กล่าวคือ ชื่อป้ายกำกับต้องไม่ซ้ำกัน (ยกเว้นป้ายกำกับในเครื่อง ดูด้านล่าง) ในฐานะตัวถูกดำเนินการ สามารถใช้ป้ายกำกับได้หลายครั้ง

ฉลากสามารถขยายได้ทั้งบรรทัด ในกรณีนี้ ค่าของเลเบลคือที่อยู่ของคำสั่งหรือคำสั่งที่ควรตามมาในบรรทัดถัดไปของโปรแกรม เมื่อกำหนดเลเบล ให้ลงท้ายด้วยโคลอนถ้าเลเบลตามด้วยคำสั่งตัวประมวลผล หากกำหนดป้ายกำกับสำหรับคำสั่ง (เมื่ออธิบายข้อมูล เซ็กเมนต์ รูทีนย่อย) เครื่องหมายโคลอนจะไม่ถูกใช้

ฟิลด์หลักในบรรทัดของโปรแกรมแอสเซมเบลอร์คือฟิลด์ช่วยในการจำ คำสั่งช่วยจำถูกคอมไพล์โดยตรงในคำสั่งเหล่านั้น โปรเซสเซอร์ Intel 8086 พวกเขาตรงกัน ไม่เหมือนกับตัวช่วยจำคำสั่ง คำสั่งไม่ได้คอมไพล์เป็นโค้ดสั่งการ แต่จะควบคุมเฉพาะแง่มุมต่างๆ ของงานคอมไพเลอร์ - ตั้งแต่ประเภทของโค้ดที่สร้างขึ้น (สำหรับตัวประมวลผล 8086, 80286, 80386 เป็นต้น) ไปจนถึงการกำหนดเซ็กเมนต์และรูปแบบของรายการที่สร้างขึ้น ไฟล์และให้เครื่องมือการเขียนโปรแกรมภาษาแอสเซมบลีระดับสูง

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

ชุดคำสั่งโปรเซสเซอร์ Intel 8086

สำหรับโปรแกรมเมอร์ ทรัพยากรหลักของคอมพิวเตอร์คือระบบคำสั่งที่ใช้ แต่ละคำสั่งของเครื่องแบ่งออกเป็นกลุ่มของบิต (ฟิลด์): ฟิลด์ opcode และฟิลด์ตัวถูกดำเนินการอย่างน้อยหนึ่งฟิลด์ opcode แสดงสิ่งที่ต้องทำ และตัวถูกดำเนินการกำหนดข้อมูลที่ต้องการโดยคำสั่ง และสามารถประกอบด้วยข้อมูลที่กำหนด ที่อยู่ของคำสั่ง ตัวชี้ทางอ้อมไปยังข้อมูลที่ได้รับ หรือข้อมูลอื่นๆ ที่เกี่ยวข้องกับข้อมูลที่ประมวลผลโดยคำสั่ง แต่ละคำสั่งมีตัวช่วยในการจำที่เกี่ยวข้อง โปรเซสเซอร์ Intel 8086 ใช้ชุดคำสั่งต่อไปนี้ ซึ่งสามารถแบ่งออกเป็นกลุ่มตามฟังก์ชันการทำงาน

แอสเซมเบลอร์ในตัว (ต่อไปนี้จะเรียกว่าแอสเซมเบลอร์อย่างง่าย) ทำให้สามารถตั้งโปรแกรมที่ระดับคำแนะนำของเครื่องแต่ละเครื่อง นี่คือข้อแตกต่างที่สำคัญระหว่างแอสเซมเบลอร์และปาสกาล และข้อดีและข้อเสียทั้งหมดรวมอยู่ที่ความแตกต่างนี้ ข้อดีคือ เมื่อเขียนโปรแกรมในภาษาแอสเซมบลี โปรแกรมเมอร์มักจะเลือกลำดับของคำสั่งเครื่องในลักษณะที่จะนำการคำนวณที่จำเป็นไปใช้อย่างรวดเร็วที่สุดโดยใช้หน่วยความจำน้อยที่สุด ในขณะที่คอมไพเลอร์ที่สมบูรณ์แบบเช่น Turbo Pascal คอมไพเลอร์ย่อมทำให้เกิดความซ้ำซ้อนซึ่งช่วยลดอัตราการคำนวณและเพิ่มต้นทุนหน่วยความจำ ในทางกลับกัน การเขียนโปรแกรมที่ระดับคำสั่งของเครื่องนั้นลำบากมาก และไม่สามารถเทียบความเร็วของการพัฒนาโปรแกรมกับการเขียนโปรแกรมในภาษาปาสกาลได้ ซึ่งเป็นข้อเสียเปรียบหลักของแอสเซมเบลอร์

ในการใช้เครื่องมือแอสเซมเบลอร์ คุณต้องมีความเข้าใจที่ชัดเจนเกี่ยวกับรายละเอียดสถาปัตยกรรมของไมโครโปรเซสเซอร์ Intel 80x86 ตระกูลนี้รวมถึงไมโครโปรเซสเซอร์:

8086 - ไมโครโปรเซสเซอร์ 16 บิตที่ใช้ใน IBM PC / XT;

8088 เป็นอะนาล็อกของ 8086 ซึ่งแตกต่างจากการโต้ตอบกับหน่วยความจำเท่านั้น: 8086 สามารถแลกเปลี่ยนทั้งไบต์และคำ 16 บิตด้วยหน่วยความจำในขณะที่ 8088 - ไบต์เท่านั้น

80286 - รุ่นปรับปรุงของ 8086 ที่ใช้ใน IBM AT PC สามารถทำงานได้ในสองโหมด: ในโหมดจริงซึ่งจำลองการทำงานของ MP 8086 ได้อย่างสมบูรณ์และในโหมดที่ได้รับการป้องกันซึ่งสามารถระบุหน่วยความจำได้มากถึง 16 MB (ในโหมดจริง - สูงสุด 1 MB);

80386 - 80286 รุ่น 32 บิต; สามารถรองรับได้ถึง 4 GB;

80486 คือการรวมกันของ 80386/80387 เช่น มีระบบย่อยภายในสำหรับการดำเนินการตามจุดลอยตัว

80586 (Pentium) - มีการปรับปรุงหลายอย่างที่ให้ประสิทธิภาพเพิ่มขึ้น 2 ... 3 เท่าเมื่อเทียบกับ 80486 รวมถึงความสามารถในการประมวลผลตัวเลข 64 บิต

ไมโครโปรเซสเซอร์ของตระกูลนี้เพิ่มความสามารถตามลำดับที่ระบุไว้ แต่เข้ากันได้อย่างเคร่งครัดจากรุ่นที่ต่ำกว่าไปจนถึงรุ่นเก่า: ทุกสิ่งที่ 8086/8088 สามารถทำได้นั้นถูกนำไปใช้โดย Pentium แต่ไม่ในทางกลับกัน สถาปัตยกรรมถูกกล่าวถึงด้านล่าง ( องค์กรภายใน, วิธีการระบุที่อยู่และระบบคำสั่ง) MP 8086/8088.



12.1.1. ทะเบียน

MP 8086/8088 มี 14 รีจิสเตอร์ ตามหน้าที่พวกเขาจะแบ่งออกเป็นกลุ่ม:

· ทะเบียนวัตถุประสงค์ทั่วไป (АХ, ВХ, СХ, DX); มีไว้สำหรับจัดเก็บตัวถูกดำเนินการและดำเนินการตามคำแนะนำพื้นฐาน สิ่งเหล่านี้สามารถใช้เป็นชุดของรีจิสเตอร์ 8 บิตอิสระสองตัว: ไบต์สูงของรีจิสเตอร์ (AH, BH, CH, DH) และไบต์ต่ำ (AL, BL, CL, DL); ตัวอย่างเช่น AX ประกอบด้วย AH และ AL;

การลงทะเบียนเซ็กเมนต์ (CS, DS, SS, ES); ใช้เพื่อระบุส่วนเมื่อระบุหน่วยความจำ

การลงทะเบียนตัวชี้ (SP, BP, IP) ใช้เพื่อระบุออฟเซ็ตเมื่อระบุหน่วยความจำ

· การลงทะเบียนดัชนี (SI, DI); ใช้สำหรับการจัดทำดัชนีที่อยู่

· ทะเบียนธง; ใช้สำหรับเก็บสัญญาณสถานะของโปรเซสเซอร์

รีจิสเตอร์ถูกใช้ในรูปแบบต่างๆ ภายในกลุ่มฟังก์ชันเดียวกัน ลักษณะเฉพาะของการใช้รีจิสเตอร์อธิบายไว้ด้านล่าง

ลงทะเบียนAX... เป็นตัวเสริมหลัก ใช้ในการคำนวณทางคณิตศาสตร์ทั้งหมด (บวก คูณ ฯลฯ) ด้วยความช่วยเหลือของ AX และกึ่งการลงทะเบียน AHIAL เท่านั้นจึงจะสามารถแลกเปลี่ยนข้อมูลกับพอร์ต I / O

ลงทะเบียน BXมันถูกใช้เป็น adder ในการดำเนินการทางคณิตศาสตร์ เช่นเดียวกับการลงทะเบียนฐานสำหรับการกำหนดที่อยู่ดัชนี

ทะเบียน CX... ส่วนใหญ่จะใช้เป็นตัวนับเมื่อดำเนินการซ้ำและกะ นอกจากนี้ยังสามารถมีส่วนร่วมในการดำเนินการทางคณิตศาสตร์

DX ลงทะเบียนใช้เป็น data register ในการดำเนินการ I / O และยังเป็น adder เมื่อประมวลผลจำนวนเต็มแบบยาว (32 บิต)

ซีเอสลงทะเบียนประกอบด้วยหมายเลขของส่วนหน่วยความจำ (ส่วนรหัส) ที่คำสั่งเครื่องปัจจุบันตั้งอยู่ เพื่อให้ได้ที่อยู่ที่สมบูรณ์ของคำสั่งถัดไป เนื้อหาจะถูกเลื่อนไปทางซ้าย 4 บิต และเพิ่มในการลงทะเบียนตัวชี้ IP เนื้อหา CS จะถูกเปลี่ยนโดยอัตโนมัติในคำสั่งกระโดดไกล (ระหว่างเซกเมนต์) และการเรียกโปรซีเจอร์

การลงทะเบียน IPกำหนดออฟเซ็ตที่สัมพันธ์กับจุดเริ่มต้นของส่วนโค้ด CS ของคำสั่งเครื่องที่ดำเนินการได้ถัดไป เนื้อหาของ IP จะถูกเปลี่ยนโดยอัตโนมัติระหว่างการดำเนินการของคำสั่ง เพื่อให้มั่นใจว่าลำดับที่ถูกต้องของการดึงคำสั่งจากหน่วยความจำ

ดีเอสลงทะเบียนประกอบด้วยจำนวนของเซ็กเมนต์หน่วยความจำ (เซ็กเมนต์ข้อมูล) ที่มีข้อมูล (ค่าคงที่และตัวแปร) ตัวแปรโกลบอลและค่าคงที่ที่พิมพ์ทั้งหมดของโปรแกรม Turbo Pascal จะอยู่ในเซ็กเมนต์เดียวที่ระบุโดยรีจิสเตอร์นี้

ลงทะเบียน SSประกอบด้วยหมายเลขเซ็กเมนต์ของสแต็ก สแต็กเป็นส่วนหนึ่งของหน่วยความจำที่แอดเดรสอัตโนมัติซึ่งใช้เพื่อจัดเก็บตัวถูกดำเนินการชั่วคราว การใช้สแต็ก TurboPascal จะจัดระเบียบการแลกเปลี่ยนข้อมูลระหว่างโปรแกรมและโพรซีเดอร์ นอกจากนี้ยังวางตัวแปรโลคัลทั้งหมด (เช่น ตัวแปรที่ประกาศภายในโพรซีเดอร์) ไว้ในนั้น หน่วยความจำสแต็กถูกใช้ตามกฎเข้าก่อนออกก่อน: ตัวถูกดำเนินการล่าสุดที่ผลักไปยังสแต็กจะเป็นคนแรกที่ถูกดึงออกจากหน่วยความจำ

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

การลงทะเบียน VRตัวชี้ฐานที่เรียกว่า อำนวยความสะดวกในการสร้างและใช้งานสแต็กในเครื่อง (เช่น สแต็คสำหรับใช้ภายในโพรซีเดอร์)

ลงทะเบียน ESการลงทะเบียนเซ็กเมนต์เพิ่มเติม ES ใช้สำหรับการแลกเปลี่ยนข้อมูลระหว่างเซกเมนต์และในการดำเนินการสตริงบางอย่าง

การลงทะเบียน SIกำหนดที่อยู่ของแหล่งข้อมูลสำหรับการกำหนดที่อยู่ข้อมูลที่จัดทำดัชนี (เช่น เมื่อประมวลผลอาร์เรย์) มักใช้ร่วมกับทะเบียน DS

ลงทะเบียน DIเมื่อจับคู่กับการลงทะเบียน 5 ปอนด์ จะกำหนดผู้รับข้อมูลสำหรับการแลกเปลี่ยนข้อมูลระหว่างกลุ่ม

ลงทะเบียนธง... แต่ละบิต (บิต) ของรีจิสเตอร์นี้มีวัตถุประสงค์ดังต่อไปนี้

CF พกธงประกอบด้วย 1 หากมีการโอนหน่วยเพิ่มหรือยืมหน่วยเมื่อลบ นอกจากนี้ยังใช้ในการดำเนินการวนซ้ำและเปรียบเทียบ

ธงพาริตี้ PFประกอบด้วย 1 ถ้าการดำเนินการส่งผลให้เป็นตัวเลขที่มีเลขนัยสำคัญเป็นจำนวนคู่ เช่น เสริมผลลัพธ์เป็นคี่ - ใช้ในการดำเนินการแลกเปลี่ยนเพื่อควบคุมข้อมูล

AF ธงพกพาภายนอกควบคุมการถ่ายโอนข้อมูลบิตที่ 3 มีประโยชน์สำหรับการดำเนินการกับตัวเลขทศนิยมที่บรรจุไว้

ZF ธงศูนย์จะเท่ากับ 1 หากผลลัพธ์ของการดำเนินการเป็นศูนย์ มิฉะนั้นจะเท่ากับ 0

ธงสัญลักษณ์เอสเอฟเท่ากับ 1 หากการดำเนินการส่งผลให้เป็นจำนวนลบ (โดยมีค่าเท่ากับ 1 ในบิตที่สำคัญที่สุด)

แฟล็กการติดตาม TFเท่ากับ 1 หากโปรแกรมดำเนินการเป็นขั้นตอน โดยมีการถ่ายโอนการควบคุมหลังจากแต่ละคำสั่งขัดจังหวะที่ดำเนินการด้วยเวกเตอร์ 1

แฟล็กขัดจังหวะ IFประกอบด้วย 1 หากเปิดใช้งานไมโครโปรเซสเซอร์เพื่อจัดการกับการขัดจังหวะ

ธงทิศทาง DFควบคุมทิศทางของการถ่ายโอนข้อมูล: หากมี 0 จากนั้นหลังจากการดำเนินการดัชนีแต่ละครั้ง เนื้อหาของการลงทะเบียนดัชนีจะเพิ่มขึ้น 1 มิฉะนั้นจะลดลง 1

ธงล้น OF.มันถูกตั้งค่าเป็นหนึ่งถ้าเป็นผลของการดำเนินการ ได้รับตัวเลขที่เกินกว่าบิตกริดของไมโครโปรเซสเซอร์

12.1.2. ที่อยู่

ในสถาปัตยกรรม MP 8086/8088 ที่อยู่ของไบต์ใดๆ จะถูกระบุด้วยคำ 16 บิตสองคำ - เซ็กเมนต์และออฟเซ็ต เมื่อสร้างที่อยู่แบบเต็ม 20 บิตที่จำเป็นสำหรับการกำหนดที่อยู่ภายใน 1 MB เซ็กเมนต์จะถูกเลื่อนไปทางซ้าย 4 บิต (คูณด้วย 16) และเพิ่มด้วยออฟเซ็ต เนื่องจากความจุของออฟเซ็ต 16 บิตคือ 65,536 ค่า จึงสามารถระบุได้ถึง 64 KB ภายในเซ็กเมนต์เดียว

สถาปัตยกรรม MP อนุญาตให้ใช้เจ็ด วิธีทางที่แตกต่างที่อยู่

ลงทะเบียน

ดึงตัวถูกดำเนินการจากการลงทะเบียนหรือวางไว้ในการลงทะเบียน ตัวอย่าง:

mov ah, bx (แยกจาก VX และวางใน AX)

เพิ่ม cx, ax (เนื้อหาของ AX ถูกเพิ่มใน CX)

ดันอดีต (ดันเนื้อหาของ CX ลงบนสแต็ก)

ทันที

ตัวถูกดำเนินการ (ค่าคงที่ 8 หรือ 16 บิต) มีอยู่ในเนื้อหาคำสั่งโดยตรง ตัวอย่าง:

mov ขวาน 100 (โหลด 100 ลงใน AX)

เพิ่มขวาน 5 (เพิ่ม 5 ให้กับเนื้อหาของ AX)

mov cx, $ ffff (เราใส่ค่า CX 65535)

ตรง

ออฟเซ็ตตัวถูกดำเนินการถูกตั้งค่าในเนื้อหาของโปรแกรมและเพิ่มในการลงทะเบียน DS ตัวอย่างเช่น:

X: คำ; B: ไบต์;

mov ah, x (เราโอนค่าของตัวแปร X ไปยังการลงทะเบียน AX)

เสริม ah, B (เพิ่มค่าของตัวแปร B ให้กับเนื้อหาของการลงทะเบียน AH)

mov X, ขวาน (เราถ่ายโอนเนื้อหาของรีจิสเตอร์ AX ไปยังพื้นที่หน่วยความจำของตัวแปร X)

ทะเบียนทางอ้อม

ที่อยู่ผู้บริหารของตัวถูกดำเนินการ (แม่นยำกว่านั้นคือ ออฟเซ็ต) มีอยู่ในการลงทะเบียน BX, BP, SI หรือ DI ตัวใดตัวหนึ่ง ในการระบุที่อยู่ทางอ้อม การลงทะเบียนนี้ต้องอยู่ในวงเล็บเหลี่ยม ตัวอย่างเช่น

mov axe (เนื้อหาของคำ 16 บิตที่เก็บไว้ในหน่วยความจำตามที่อยู่ DS: BX ถูกโอนไปยัง AX register);

การลงทะเบียน BX ... DI แต่ละรายการทำงานกับการลงทะเบียนเซ็กเมนต์ของตัวเองโดยค่าเริ่มต้น:

DS: BX, SS: BP, DS: SI, ES: DI

อนุญาตให้มีการระบุอย่างชัดเจนของการลงทะเบียนเซ็กเมนต์ หากแตกต่างจากค่าดีฟอลต์ ตัวอย่างเช่น:

ฐานที่อยู่

รีจิสเตอร์ฐาน BX (หรือ BP) มีฐาน (ที่อยู่ของจุดเริ่มต้นของชิ้นส่วนหน่วยความจำบางส่วน) ซึ่งสัมพันธ์กับที่แอสเซมเบลอร์คำนวณออฟเซ็ต ตัวอย่างเช่น:

mov ax, [bx] +10 (เราโหลดลงใน AX ไบต์ที่ 10 จากจุดเริ่มต้นของฐานหน่วยความจำตามที่อยู่ DS-.BX);

ที่อยู่ที่จัดทำดัชนี

หนึ่งในดัชนีรีจิสเตอร์ SI หรือ DI ระบุตำแหน่งขององค์ประกอบที่สัมพันธ์กับจุดเริ่มต้นของพื้นที่หน่วยความจำบางส่วน ตัวอย่างเช่น ให้ AOB เป็นชื่อของอาร์เรย์ของค่าไบต์ จากนั้นคุณสามารถใช้ส่วนย่อยต่อไปนี้:

mov si, 15 (เราใส่ค่าคงที่ 15 ใน SI)

mov ah, AOB (เราส่งไปยัง AN ไบต์ที่ 16 ตามลำดับจากจุดเริ่มต้นของอาร์เรย์)

mov AOB อ่า (เราส่งที่ได้รับไปยังองค์ประกอบแรกของอาร์เรย์)

การกำหนดที่อยู่ฐานข้อมูลด้วยการจัดทำดัชนี

ตัวแปรของการกำหนดแอดเดรสดัชนีสำหรับเคสเมื่อพื้นที่หน่วยความจำที่จัดทำดัชนีถูกระบุโดยฐาน ตัวอย่างเช่น:

การระบุที่อยู่ประเภทนี้สะดวกเมื่อจัดการ อาร์เรย์สองมิติ... ตัวอย่างเช่น ถ้า AOB เป็นอาร์เรย์ขนาด 10x10 ไบต์ของฟอร์ม

AOB: อาร์เรย์ของไบต์;

จากนั้นเพื่อเข้าถึงองค์ประกอบ AOB คุณสามารถใช้ส่วนย่อยต่อไปนี้

mov bx, 20 (เส้นฐาน 2)

mov si, 2 (หมายเลของค์ประกอบที่ 3)

mov ขวาน AOB (การเข้าถึงองค์ประกอบ)

12.1.3. ระบบสั่งการ

ตารางด้านล่างระบุตัวช่วยจำของคำสั่งที่ถูกต้องทั้งหมดสำหรับ MP 8086/8088 เพื่อความสะดวกในการใช้งาน คำสั่งทั้งหมดจะถูกแบ่งออกเป็น 6 กลุ่มการทำงาน - การถ่ายโอนข้อมูล, เลขคณิต, ระดับบิต, สตริง, การถ่ายโอนการควบคุม, การขัดจังหวะ ภายในแต่ละกลุ่ม ทีมจะรวมกันเป็นกลุ่มย่อยตามลักษณะเพิ่มเติมทั่วไป

การวิเคราะห์โดยละเอียดของคำสั่ง MP 8086/8088 ทั้งหมดจะใช้พื้นที่มากเกินไป ดังนั้นคำอธิบายตามตารางจึงครอบคลุมเฉพาะคำสั่งยอดนิยมเท่านั้น คำอธิบายโดยละเอียดของคำสั่งทั้งหมดสามารถพบได้ใน

คำสั่งถ่ายโอนข้อมูล

ช่วยในการจำ รูปแบบ คำอธิบาย
คำสั่งทั่วไป
MOV ตัวรับ MOV, แหล่งที่มา มูลค่าส่งต่อ
ดัน แหล่งผลักดัน วางบนกอง
โผล่ ตัวรับ POP ป๊อปจากกอง
XCHG ตัวรับ XCHG แหล่งที่มา ค่าแลกเปลี่ยน
XLAT ตาราง XLAT โหลดไบต์จากตารางลงใน AL
คำสั่ง I/O
ใน พอร์ตแบตเตอรี่ อ่านจากพอร์ต
ออก พอร์ต OUT, แบตเตอรี่ เขียนถึงพอร์ต
คำสั่งการส่งต่อที่อยู่
LEA รีจิสเตอร์ LEA 16 หน่วยความจำ 16 อัพโหลดที่อยู่ผู้บริหาร
LDS ทะเบียนแอลดีเอส 16 หน่วยความจำ 32 โหลดลงใน DS: register16 full address
LES LES รีจิสเตอร์ 16 หน่วยความจำ 32 โหลดลงใน ES: register16 ที่อยู่เต็ม
คำสั่งการส่งต่อแฟล็ก
LAHF LAHF อัปโหลดแฟล็กไปที่NA
SAHF SAHF ตั้งค่าสถานะจาก NA
PUSH PUSH ติดธงบน stack
POPF POPF ธงป๊อปจากสแต็ก

หนึ่งในคำแนะนำที่ใช้บ่อยที่สุด MOV ช่วยให้คุณถ่ายโอนไบต์หรือคำอย่างปลอดภัยจากการลงทะเบียนไปยังการลงทะเบียน จากหน่วยความจำไปยังการลงทะเบียน หรือจากการลงทะเบียนไปยังหน่วยความจำ ประเภทของข้อมูลที่ถ่ายโอน (ไบต์หรือคำ) ถูกกำหนดโดยการลงทะเบียนที่เกี่ยวข้องกับการถ่ายโอน ต่อไปนี้เป็นตัวอย่างการใช้คำสั่ง:

mov ah, ตาราง (โอนคำจากหน่วยความจำไปยัง AX)

mov ตาราง ah (โอนไบต์จาก AN ไปยังหน่วยความจำ)

mov ds, ขวาน (โอนไปยังส่วนข้อมูล)

mov es:, ขวาน (การถ่ายโอนคำไปยังหน่วยความจำ: การกำหนดที่อยู่แทนที่ส่วนพื้นฐาน)

mov ch, -17 (ส่งค่าคงที่ลงทะเบียน)

mov ตาราง $ FF (ส่งค่าคงที่ไปยังหน่วยความจำ)

คุณไม่สามารถส่งด้วย MOV:

จากหน่วยความจำสู่หน่วยความจำ เช่น แทนที่จะเป็น

ควรใช้

ค่าคงที่หรือตัวแปรใน DS เช่น ไม่สามารถ

ส่วนหนึ่งลงทะเบียนกับอีกส่วนหนึ่ง ตัวอย่างเช่น คุณไม่สามารถ

· เพื่อลงทะเบียน CS; ค่าของการลงทะเบียนนี้ (ส่วนรหัส) จะเปลี่ยนแปลงโดยอัตโนมัติเมื่อดำเนินการคำสั่ง CALL และ JMP ที่ห่างไกล นอกจากนี้ยังโหลดจากสแต็กเมื่อดำเนินการคำสั่ง RETF (ออกจากขั้นตอนไกล)

คำแนะนำสแต็ก PUSH และ POP นั้นใช้กันอย่างแพร่หลายในการจัดเก็บการลงทะเบียนและข้อมูลชั่วคราว เช่นเดียวกับการแลกเปลี่ยนค่าระหว่างการลงทะเบียน แต่ละคนทำงานด้วยคำเช่น ไบต์เดียวไม่สามารถผลักหรือป๊อปอัพลงบนสแต็กได้ เมื่อดำเนินการ PUSH เนื้อหาของตัวชี้ SP จะลดลงก่อน 2 จากนั้นตัวถูกดำเนินการจะอยู่ที่ SS: SP เมื่อแตกจากสแต็ก หน่วยความจำที่แอดเดรส SS: SP จะถูกอ่านก่อน จากนั้น SP จะเพิ่มขึ้น 2 ดังนั้นเมื่อเติม ตัวชี้ที่ด้านบนของสแต็ก SP จะเลื่อนไปที่แอดเดรสด้านล่าง และเมื่อปล่อย ให้กับผู้ที่สูงกว่า เมื่อทำงานกับสแต็ก ให้จดจำลักษณะเฉพาะของการใช้หน่วยความจำสแต็ก (“เข้าก่อน ออกก่อน”) และหน่วยความจำนี้ถูกใช้อย่างมากเมื่อเรียกใช้โพรซีเดอร์ เช่น สถานะของสแต็ก ณ เวลาที่ออกจากโพรซีเดอร์จะต้องประสานงานกับงานต่อไปของโปรแกรมอย่างเคร่งครัด เงื่อนไขแรกกำหนดลำดับที่ข้อมูลถูกดึงออกจากสแต็ก - จะต้องตรงกันข้ามกับลำดับที่ข้อมูลนี้ถูกผลักไปที่สแต็ก เงื่อนไขที่สองจริง ๆ แล้วหมายความว่าหลังจากออกจากโพรซีเดอร์แล้ว ตัวชี้ SP จะต้องมีค่าออฟเซ็ตเดียวกันกับในขณะที่ป้อน กล่าวอีกนัยหนึ่ง โพรซีเดอร์ไม่ควร "ลืม" คำพิเศษในสแต็ก หรือใช้มากกว่าที่จำเป็นจากนั้น

คำสั่งที่อยู่โหลด LEA จะโหลดที่อยู่ (ออฟเซ็ต) ของพื้นที่หน่วยความจำที่ต้องการลงในรีจิสเตอร์ สามารถทำได้เช่นเดียวกันโดยใช้คำสงวน OFFSET ก่อนชื่อตัวแปร ตัวอย่างเช่น:

mov ขวาน, OFFSET X (โหลดออฟเซ็ต X เป็น AX)

ขวาน X (การกระทำเดียวกัน)

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

คำสั่งการโหลดที่อยู่อีกสองคำสั่งคือ LDS และ LES โหลดคำ 16 บิตแรกจากต้นทางลงในรีจิสเตอร์ปลายทาง จากนั้นจึงป้อนคำถัดไปลงในรีจิสเตอร์ DS หรือ ES เช่น ออกแบบมาเพื่อโหลดที่อยู่ของตัวถูกดำเนินการทั้งหมด (ส่วนและออฟเซ็ต)

คำสั่งเลขคณิต

ช่วยในการจำ รูปแบบ ความคิดเห็น
คำสั่งเพิ่มเติม
เพิ่ม เพิ่มผู้รับ, แหล่งที่มา พับ
ADC ตัวรับ ADC แหล่งที่มา พับ ใส่ยัติภังค์
AAA AAA การเพิ่มที่ถูกต้องสำหรับตาราง ASCII
DAA DAA การบวกเลข BCD ที่ถูกต้อง
INC ตัวรับ INC เพิ่มขึ้นทีละหนึ่ง
คำสั่งลบ
SUB ตัวรับ SUB, แหล่งที่มา ลบ
SBB ตัวรับ SBB, แหล่งที่มา ลบด้วยเงินกู้
AAS AAS การลบที่ถูกต้องสำหรับตาราง ASCII
DAS DAS การลบที่ถูกต้องสำหรับตัวเลข bcd
ธ.ค. ตัวรับธันวาคม ลดลงหนึ่ง
NEG เครื่องรับ NEG กลับเครื่องหมาย
CMP ตัวรับ CMP แหล่งที่มา เปรียบเทียบ
คำสั่งคูณ
มูล แหล่ง MUL ตัวคูณที่ไม่ได้ลงชื่อ
IMUL แหล่งที่มาของ IMUL ลงชื่อคูณ
AAM AAM การคูณที่ถูกต้องสำหรับตาราง ASCII
กองบัญชาการ
DIV แหล่ง DIV แบ่งปันไม่ได้ลงนาม
IDIV แหล่ง IDIV แบ่งปันด้วยเครื่องหมาย
AAD AAD การแบ่งที่ถูกต้องสำหรับตาราง ASCII
คำสั่งขยายเครื่องหมาย
CBW CBW แปลงไบต์เป็น word
CWD CWD แปลงคำเป็นคำคู่

เมื่อใช้คำสั่งเลขคณิต โปรดจำไว้ว่า MT สามารถจัดการกับตัวเลขที่มีลายเซ็น ตัวเลขที่ไม่ได้ลงนาม และเลขฐานสอง-ทศนิยม ในตัวเลขที่ไม่มีเครื่องหมาย บิตทั้งหมดจะใช้แทนค่า เหล่านั้น. พวกมันเทียบเท่ากับประเภท Byte และ Word ในขณะที่ตัวเลขที่ลงนามในลำดับสูงเก็บเครื่องหมายของตัวเลขและเทียบเท่ากับประเภท Shortlnt และ Integer BCD ใช้ 4 บิตสำหรับทศนิยมแต่ละตำแหน่งและสามารถบรรจุหรือคลายการแพ็คได้ ในกรณีแรก หนึ่งไบต์เก็บทศนิยม 2 หลัก (ส่วนที่สำคัญที่สุดอยู่ในตอดที่สำคัญที่สุด) ในอันที่สอง - อันเดียวเท่านั้น (ไม่ใช้แทะที่สำคัญที่สุด) คำสั่งเลขคณิตพื้นฐานของ MP (ADD, SUB, MUL, DIV) ไม่ได้คำนึงถึงรูปแบบทศนิยมฐานสองของการแทนตัวเลข ดังนั้น คำสั่งสำหรับการแก้ไขผลลัพธ์จึงรวมอยู่ในสถาปัตยกรรมของ MP

คำสั่งบิต

ช่วยในการจำ รูปแบบ ความคิดเห็น
คำสั่งลอจิก
และ และจม, แหล่งที่มา ดำเนินการ และ
หรือ หรืออ่างล้างจาน, แหล่งที่มา ดำเนินการ OR
XOR ตัวรับ XOR, แหล่งที่มา ดำเนินการXOR
ไม่ ไม่ใช่ผู้รับ ดำเนินการไม่
ทดสอบ ตัวรับการทดสอบ, แหล่งที่มา ตรวจสอบ
คำสั่งเฉือน
SAL / SHL เครื่องรับ SAL เคาน์เตอร์ เขยิบไปทางซ้าย
SAR / SHR ตัวรับ SAR ตัวนับ เขยิบขวา
ROL ตัวรับ ROL ตัวนับ เลื่อนไปทางซ้ายเป็นวัฏจักร
ROR ตัวรับ ROR ตัวนับ เลื่อนไปทางขวาเป็นวงกลม
RCL ตัวรับ RCL ตัวนับ เขยิบซ้าย Wrap
RCR ตัวรับ RCR ตัวนับ เขยิบขวา Wrap

คำแนะนำบิตใช้ในการคำนวณนิพจน์เชิงตรรกะ เช่นเดียวกับในกรณีเหล่านั้นเมื่อจำเป็นต้องเปลี่ยนแต่ละบิตของตัวถูกดำเนินการ คำแนะนำเชิงตรรกะ AND, OR, XOR และ NOT เทียบเท่ากับการดำเนินการ Turbo Pascal ที่สอดคล้องกันเมื่อตัวถูกดำเนินการเป็นนิพจน์จำนวนเต็ม คำสั่ง TEST ดำเนินการเพิ่มจำนวนเต็มระดับบิต AND แต่ไม่เปลี่ยนค่าของตัวถูกดำเนินการ แต่ตั้งค่าสถานะตามค่าของผลการเปรียบเทียบเท่านั้น: ศูนย์ CF และ OF เปลี่ยน PF, ZF, SF และ ไม่เปลี่ยน AF (แฟล็ก ZF จะถูกตั้งค่าเป็น 1 ถ้าเมื่อตัวถูกดำเนินการทั้งสองมีบิตที่สอดคล้องกันอย่างน้อยหนึ่งบิต) คำสั่ง SHL / SHR shift เทียบเท่ากับการทำงานของ Turbo Pascal ที่มีชื่อเดียวกันและแตกต่างจากคำสั่ง cyclic shift ของ ROLIROR โดยที่บิตที่สำคัญที่ถูกแทนที่ระหว่างการดำเนินการจะหายไป ในขณะที่ระหว่าง cyclic shift บิตเหล่านี้จะปรากฏ "อีกด้านหนึ่ง" ตัวอย่างเช่น หากคุณรัน snippet

mov al, 1 (หน่วยโหลดใน AL)

sh al, 1 (เลื่อนไปทางขวา 1 บิต)

การลงทะเบียน AL จะมี 0 (อันที่จองไว้จะถูกวางไว้ใน CF) ในขณะที่หลังจากแทนที่คำสั่ง SHR ด้วย ROR มันจะมีค่า $ 80 = 128 (อันที่จองไว้จะถูกวางไว้ในบิตที่สำคัญที่สุดของ ลงทะเบียน).

โปรดทราบว่าตัวนับคำสั่ง shift สามารถเป็น 1 หรือจำนวนกะที่ระบุในการลงทะเบียน CL

คำสั่งควบคุมการโอน

ช่วยในการจำ รูปแบบ ความคิดเห็น
กระโดดแบบไม่มีเงื่อนไข
เรียก ชื่อเรียก เข้าสู่ขั้นตอน
RET RET [จำนวนพารามิเตอร์] กลับจากขั้นตอน
กระโดด กระโดดชื่อ ไปที่
การแตกแขนงแบบมีเงื่อนไข
JA / JNBE JA close_label ข้ามหากอยู่ด้านบน (หลังจากเปรียบเทียบตัวถูกดำเนินการที่ไม่ได้ลงนาม)
JAE / JNB JAE close_label กระโดดถ้าสูงกว่าหรือเท่ากัน
JB / JBAE / JC JB close_label กระโดดถ้าด้านล่าง
JBE / JNA JBE close_label กระโดดถ้าต่ำกว่าหรือเท่ากัน
JCXZ JCXZ close_label กระโดดถ้า CX = 0
JE / JZ JE close_label กระโดดถ้าเท่ากัน
JG / JNLE JG close_label Jump if Greater (หลังจากเปรียบเทียบตัวถูกดำเนินการที่ลงนามแล้ว)
JGE / JNL LGE close_label กระโดดถ้ามากกว่าหรือเท่ากับ
JL / JNGE JL close_label กระโดดถ้าน้อย
JLE / JNG JLE close_label กระโดดถ้าน้อยกว่าหรือเท่ากับ
JNC JNC close_label ข้ามไปหากไม่มีการยกยอด
JNE / JNZ JNE close_label กระโดดถ้าไม่เท่ากัน
JNO JNO close_label กระโดดถ้าน้ำไม่ล้น
JNP / JPO JNP close_label กระโดดถ้าคี่
โจ้ JO close_label กระโดดถ้าพกพา
JP / JPE Jp close_label กระโดดถ้าเท่ากัน
Js JS close_label กระโดดถ้าเป็นลบ
คำสั่งวนรอบ
LOOP LOOP close_label วนซ้ำ
LOOPE / LOOPZ LOOPE close_label ทำซ้ำจนเท่ากัน
LOOPNE / LOOPNZ LOOPNE close_label ทำซ้ำจนไม่เท่ากัน

คำแนะนำการข้ามแบบไม่มีเงื่อนไข CALL, RET, JMP สามารถใช้โมเดลหน่วยความจำที่อยู่ไกลหรือใกล้ได้ ในขณะที่คำแนะนำการข้ามแบบมีเงื่อนไขสามารถใช้ได้เฉพาะรุ่นขนาดเล็กเท่านั้น (ภายใน -128 ... + 127 ไบต์) ด้วยโมเดลหน่วยความจำไกล (กำหนดโดยตัวเลือก Options / Compiler / Force far calls ของสภาพแวดล้อม Turbo Pascal หรือโดยคำสั่งคอมไพเลอร์ (F +)) ทั้งภายในเซ็กเมนต์และการถ่ายโอนการควบคุมระหว่างส่วนจะดำเนินการในระยะใกล้ ฟิลด์ - ภายในเซ็กเมนต์เท่านั้น

คำสั่ง CALL ทำงานดังนี้ ขั้นแรก ที่อยู่ของคำสั่งหลังจาก CALL (ที่อยู่ผู้ส่งกลับ) จะถูกผลักไปที่สแต็ก จากนั้นที่อยู่ของจุดป้อนโพรซีเดอร์จะอยู่ในการลงทะเบียน IP (หรือในคู่ CS: IP) ดังนั้นคำสั่งแรกของ ขั้นตอนจะดำเนินการทันทีหลังจากคำสั่ง CALL ที่อยู่ทั้งสอง (จุดเข้าและจุดกลับ) จะเป็นออฟเซ็ต 16 บิตสำหรับการโทรภายในเซ็กเมนต์ หรือที่อยู่แบบเต็ม 32 บิตสำหรับการโทรระหว่างเซกเมนต์ ขั้นตอน Pascal (ฟังก์ชัน) ทั้งหมดที่แปลในโหมด (F +) หรือมี FAR ในส่วนหัวจะต้องเรียกว่า far ในการดำเนินการนี้ ควรระบุรุ่นหน่วยความจำหลังคำสั่ง CALL:

ขั้นตอน MyProc; ไกล;

โทร FAR MyProc (เรียกขั้นตอนที่ห่างไกล)

รูทีนไลบรารีทั้งหมด (กล่าวคือ รูทีนที่ประกาศในส่วนอินเตอร์เฟสของโมดูล) ควรถูกเรียกในลักษณะเดียวกัน เมื่อใช้การโทรทางไกล เนื้อหาของส่วนโค้ด CS จะถูกผลักไปที่สแต็กก่อน จากนั้นจึงค่อยส่งกลับออฟเซ็ตเท่านั้น

เมื่อออกจากขั้นตอนไกล คำสั่ง RET จะแสดงคำทั้ง 16 บิตจากสแต็กและใส่คำแรกใน IP และคำที่สองใน CS และเมื่อออกจากโพรซีเดอร์ Near จะแสดงเฉพาะออฟเซ็ตจากสแต็กแล้วใส่เข้าไป ไอพี

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

หน้า อ่า 0 (กำลังตรวจสอบ AH)

[ป้องกันอีเมล] (ขวาน = 0?)

jmp IsZero (ใช่ - ไปที่ฉลากไกล)

....... (ไม่ - เรายังคงทำงาน)

ในตาราง คำว่า "สูง / ต่ำ" ใช้เพื่ออ้างถึงตัวถูกดำเนินการที่ไม่ได้ลงนาม และ "มากกว่า / น้อยกว่า" ใช้เพื่อเปรียบเทียบตัวถูกดำเนินการที่ลงนาม

เนื่องจากการข้ามแบบมีเงื่อนไขใช้การแตกแขนงโปรแกรมโดยอิงจากการตรวจสอบแฟล็ก จึงมักนำหน้าด้วยคำสั่งที่เปลี่ยนแฟล็กเหล่านั้น ส่วนใหญ่มักจะเป็นคำสั่งเปรียบเทียบ CMP ด้านล่างนี้คือการรวมกันของ CMP - conditional_transition สำหรับอัตราส่วนตัวรับ / แหล่งที่มาต่างๆ (ตัวถูกดำเนินการที่หนึ่งและที่สอง) ของคำสั่ง CMP:

ตัวอย่างเช่น:

cmp ah, 5 (AH> 5?)

จ๋า @AboveS (ใช่มากขึ้น - ไปต่อ)

หน้า bx, - 3 (BX<=-3 ?}

เจเล่ @ LessM3 (ใช่ น้อยกว่าหรือเท่ากับ)

คำสั่ง LOOP / LOOPE / LOOPNE ใช้เพื่อจัดระเบียบลูป พวกเขาทั้งหมดใช้เนื้อหาของการลงทะเบียน CX เป็นตัวนับการทำซ้ำ คำสั่ง LOOP จะลดค่า CX ลงหนึ่งรายการและโอนการควบคุมไปยังเลเบลเริ่มต้นการวนซ้ำหากเนื้อหาของรีจิสเตอร์นี้ไม่ใช่ศูนย์ คำสั่ง LOOPE / LOOPNE ยังลดตัวนับ CX ด้วย แต่ถ่ายโอนการควบคุมไปยังจุดเริ่มต้นของวงจรหากตั้งค่าสถานะ ZF (หรือเคลียร์) และตัวนับ CX ไม่เท่ากับศูนย์

ตัวอย่างเช่น คุณสามารถค้นหาศูนย์ไบต์ในอาร์เรย์ AOB:

AOB: อาร์เรย์ของไบต์;

mov อดีต มัน) 00 (เราเริ่มต้นเคาน์เตอร์ CX)

ลี บีเอ็กซ์, AOB (เราใส่ที่อยู่ของ AOB ใน VX)

ธ.ค. bx (เตรียมรอบ)

(นี่คือจุดเริ่มต้นของรอบการตรวจสอบ)

@@ ทดสอบ: inc bx (ที่อยู่ไบต์ถัดไป)

cmp BYTE PTR, 0 (ตรวจสอบไบต์)

ลูปเน่ © Test (ปิดรอบ)

jnz © NotZero (หากไม่พบ null byte)

....... (พบศูนย์ไบต์)

คำสั่งสตริง

ช่วยในการจำ รูปแบบ

คู่มือนี้มีเนื้อหาสำหรับการปฏิบัติงานในห้องปฏิบัติการครั้งแรกในการทำงานกับภาษาแอสเซมบลี

1. ผู้ประกอบไมโครโปรเซสเซอร์ Intel 8086/8088

1.1. รูปแบบตัวดำเนินการแอสเซมเบลอร์

ตัวดำเนินการของภาษาแอสเซมบลีของพีซีมีรูปแบบต่อไปนี้:

[<метка> :]<префикс> <код операции > [<спиcок операндов >1 [<комментарии>].

โปรแกรมเขียนในรูปแบบอิสระนั่นคือกฎสำหรับการกรอกตำแหน่งบรรทัดไม่ได้กำหนดไว้เป็นพิเศษ อัฒภาคที่จุดเริ่มต้นของบรรทัดหมายความว่าบรรทัดที่กำหนดเป็นบรรทัดแสดงความคิดเห็น

โปรแกรมสามารถเขียนได้ทั้งตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก ป้ายกำกับที่มีความยาวตามอำเภอใจควรเขียนตั้งแต่ต้นบรรทัดและคั่นด้วยเครื่องหมายทวิภาคแยกจาก opcode ซึ่งสามารถตามด้วยจำนวนช่องว่างตามอำเภอใจ (จนถึงท้ายบรรทัด)

opcode ต้องแยกออกจากรายการตัวถูกดำเนินการด้วยช่องว่างอย่างน้อยหนึ่งช่อง ตัวถูกดำเนินการแยกจากกันด้วยเครื่องหมายจุลภาค

1.2. การกำหนดฟิลด์หน่วยความจำสำหรับการจัดสรรข้อมูล

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

DB - กำหนดฟิลด์ไบต์เดียว DW - กำหนดคำ (ฟิลด์สองไบต์), DD - กำหนดคำสองคำ (ฟิลด์สี่ไบต์)

รูปแบบคำสั่ง:
DB
[<имя поля>] DW [< количество >ดับ (] (<список чисел >}[)]
ดีดี?

ที่ไหน<количество >- จำนวนฟิลด์หน่วยความจำที่มีความยาวที่ระบุซึ่งกำหนดโดยคำสั่งนี้ (ระบุว่ามีการกำหนดฟิลด์หน่วยความจำมากกว่าหนึ่งฟิลด์) ? - ใช้สำหรับจองหน่วยความจำ

มายกตัวอย่างกัน
  1. เขียนเลขฐานสิบ 23 ลงในไบต์หน่วยความจำและกำหนดชื่อ a ให้กับไบต์นี้:
    ดีบี 23.
  2. สำรองหน่วยความจำ 1 ไบต์: db?
  3. เขียนเลขฐานสิบหก 1234: dw 1234H ลงในคำในหน่วยความจำ
  4. กำหนดหน่วยความจำ 31 ไบต์โดยทำซ้ำลำดับ 1, 2, 3, 4, 5, 1, 2, 3, 4, ...:
    db 31 ซ้ำ (1,2,3,4,5)

บันทึก. เมื่อเขียนคำลงในหน่วยความจำ ไบต์ที่มีนัยสำคัญน้อยที่สุดจะถูกเขียนลงในฟิลด์ด้วยที่อยู่ต่ำสุด ตัวอย่างเช่น ในตัวอย่างที่ 3 หากทำการบันทึกที่ 100 ดังนั้น 34H จะถูกเขียนที่ 100 และ 12H ที่ 101

1.3. ตัวดำเนินการคำสั่งแอสเซมเบลอร์

ตัวถูกดำเนินการของคำสั่งแอสเซมเบลอร์สามารถกำหนดได้โดยตรงในคำสั่ง ซึ่งอยู่ในรีจิสเตอร์หรือในหน่วยความจำหลัก

ข้อมูลที่เขียนโดยตรงไปยังคำสั่งจะเรียกว่าตัวอักษร ดังนั้นในทีม
mov ah, 3 3 เป็นตัวอักษร

หากตัวถูกดำเนินการของคำสั่งแอสเซมเบลอร์อยู่ในรีจิสเตอร์ ชื่อของรีจิสเตอร์จะถูกระบุในคำสั่งที่เกี่ยวข้อง (หากรีจิสเตอร์ที่ใช้ไม่ได้ระบุไว้สำหรับคำสั่งนี้โดยเฉพาะ ตัวอย่างเช่น ในตัวอย่างข้างต้น ah คือชื่อของ ทะเบียนสะสม

การกำหนดแอดเดรสของตัวถูกดำเนินการที่อยู่ในหน่วยความจำหลักอาจเป็นได้ทั้งทางตรงและทางอ้อม เมื่อใช้ direct addressing คำสั่งจะระบุชื่อเชิงสัญลักษณ์ของฟิลด์หน่วยความจำที่มีข้อมูลที่จำเป็น เช่น

inc OPND

ที่นี่ OPND เป็นชื่อสัญลักษณ์ของฟิลด์หน่วยความจำที่กำหนดโดยคำสั่งแอสเซมเบลอร์

OPND DW?

เมื่อแปลโปรแกรม แอสเซมเบลอร์จะแทนที่ชื่อสัญลักษณ์ด้วยที่อยู่การดำเนินการของฟิลด์หน่วยความจำที่ระบุ (ออฟเซ็ตสัมพันธ์กับจุดเริ่มต้นของเซ็กเมนต์) และจะใส่ที่อยู่นี้แทนออฟเซ็ตดัชนี การระบุในกรณีนี้จะดำเนินการตามรูปแบบ: BP +<индексное смещение>แต่เนื้อหาของทะเบียน BP ไม่ได้ใช้ในการคำนวณที่อยู่ของผู้บริหาร (กรณีพิเศษ)

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


OPND
OPND +
+

รูปแบบการเขียนที่อยู่ทางอ้อมข้างต้นถูกตีความในลักษณะเดียวกัน

เมื่อแปลโปรแกรม แอสเซมเบลอร์จะกำหนดรูปแบบการกำหนดแอดเดรสที่ใช้และสร้างคำสั่งเครื่องตามลำดับ ในขณะที่ชื่อสัญลักษณ์จะถูกแทนที่ด้วยออฟเซ็ตที่สัมพันธ์กับจุดเริ่มต้นของเซ็กเมนต์ เช่นเดียวกับในกรณีของการกำหนดแอดเดรสโดยตรง

บันทึก. เมื่อใช้การระบุที่อยู่ทางอ้อมตามแผน BP +<индексное смещение>ไม่สามารถละเว้นดัชนีออฟเซ็ตได้ เนื่องจากกรณีพิเศษของการกำหนดแอดเดรสตามแบบแผนนี้ซึ่งมีความยาวศูนย์ของออฟเซ็ตดัชนีถูกใช้เพื่อจัดระเบียบการกำหนดแอดเดรสโดยตรง ดังนั้น ในกรณีที่ไม่มีดัชนีออฟเซ็ต คำสั่งควรระบุออฟเซ็ตดัชนีศูนย์ เช่น [BP + 0].

นี่คือตัวอย่างสองตัวอย่าง: และ + +6 .

ในกรณีแรก ที่อยู่การดำเนินการของตัวถูกดำเนินการจะถูกกำหนดโดยผลรวมของเนื้อหาของการลงทะเบียน bx และออฟเซ็ตดัชนีที่ระบุโดยชื่อสัญลักษณ์ "a" และในวินาที ผลรวมของเนื้อหาของ bp si รีจิสเตอร์และดัชนีชดเชยเท่ากับ 6

ความยาวของตัวถูกดำเนินการสามารถกำหนดได้:

  • ก) รหัสคำสั่ง - ในกรณีที่คำสั่งที่ใช้ประมวลผลข้อมูลที่มีความยาวที่กำหนดซึ่งกำหนดไว้เป็นพิเศษ
  • b) ขนาดของรีจิสเตอร์ที่ใช้เก็บตัวถูกดำเนินการ (1 หรือ 2 ไบต์)
  • c) ตัวชี้พิเศษ byte ptr (1 ไบต์) และ word ptr (2 ไบต์) ซึ่งใช้ในกรณีที่ไม่สามารถกำหนดความยาวของตัวถูกดำเนินการในลักษณะอื่นได้ ตัวอย่างเช่น,
    mov ไบต์ ptr x, 255
    นั่นคือตัวถูกดำเนินการถูกส่งไปยังฟิลด์ชื่อ "x" และมีความยาว I ไบต์

1.4. คำสั่งโอน/แปลงข้อมูล

1. คำสั่งถ่ายโอนข้อมูล

MOV<адрес приемника> ,< адрес источника>

ใช้ในการถ่ายโอนข้อมูลความยาว I หรือ 2 ไบต์จากการลงทะเบียนไปยังการลงทะเบียน จากการลงทะเบียนไปยังหน่วยความจำหลัก จากหน่วยความจำหลักไปยังการลงทะเบียน ตลอดจนการเขียนข้อมูลที่เขียนโดยตรงไปยังคำสั่งลงในการลงทะเบียนหรือหน่วยความจำหลัก การโอนทั้งหมดที่เป็นไปได้จะแสดงในรูปที่ 6.

มายกตัวอย่างกัน
  • a) mov axe, bx - ถ่ายโอนเนื้อหาของ bx register ไปยัง axe register;
  • b) mov cx, exword - ถ่ายโอน 2 ไบต์ที่อยู่ในฟิลด์ exword จากหน่วยความจำหลักไปยัง cx register;
  • c) mov si, 1,000 - เขียนหมายเลข 1,000 ไปยังลงทะเบียน si;
  • d) mov word ptr, 4 - เขียนตัวเลข 4 2 ไบต์ยาวลงในหน่วยความจำหลักตามที่อยู่

คำสั่งโอนสองคำสั่งใช้เพื่อโหลดที่อยู่ "ส่งต่อ" ลงในการลงทะเบียนเซกเมนต์:

mov ขวาน, รหัส
mov ds, ขวาน

2. คำสั่งแลกเปลี่ยนข้อมูล

XCHG<операнд 1> , <операнд 2>

จัดการแลกเปลี่ยนเนื้อหาของสองรีจิสเตอร์ (ยกเว้นเซ็กเมนต์) หรือรีจิสเตอร์และฟิลด์ของหน่วยความจำหลัก ตัวอย่างเช่น:

xchg bx, cx - แลกเปลี่ยนเนื้อหาของการลงทะเบียน bx และ cx

3. คำสั่งดาวน์โหลดที่อยู่ผู้บริหาร

LEA< операнд l > , < операнд 2 >

คำนวณที่อยู่ที่มีประสิทธิภาพของตัวถูกดำเนินการที่สอง และวางไว้ในฟิลด์ที่ตัวถูกดำเนินการแรกชี้ไปในฟิลด์ นี่คือตัวอย่างบางส่วน:

  • lea bx, exword - exword ที่อยู่ผู้บริหารถูกโหลดลงใน bx register;
  • lea bx, - ที่อยู่ของไบต์ที่ l0 สัมพันธ์กับจุดที่ชี้ไปที่ที่อยู่ในการลงทะเบียน di จะถูกโหลดลงใน bx register

4. คำสั่งโหลดตัวชี้

LDS< регистр > ,<операнд 2>
น้อย< регистр > ,<операнд 2>

คำสั่ง LDS โหลดการลงทะเบียน DS:< регистр>ตัวชี้ (< адрес сегмента > : < исполнительный адрес >) อยู่ที่ที่อยู่ที่ระบุในตัวถูกดำเนินการที่สอง

คำสั่ง LЕS จะโหลดตัวชี้ไปยังที่อยู่ที่อยู่ในตัวถูกดำเนินการที่สองลงในการลงทะเบียน ЕS:< регистр> .

ตัวอย่างเช่น:

lds si, exword

เช่น. คำ (2 ไบต์) ที่ที่อยู่ exword ถูกโหลดลงใน si และที่ที่อยู่ exword + 2 ลงใน ds

5. คำสั่งเขียนลง stack

ดัน< операнд>

จัดระเบียบการเขียนลงบนสแต็กของคำที่ระบุที่อยู่ในตัวถูกดำเนินการ ตัวอย่างเช่น;
push dx - เก็บเนื้อหาของ dx register ใน stack

6. คำสั่งให้กู้คืนจาก stack

โผล่< операнд>

จัดระเบียบการอ่านจากสแต็กของคำสุดท้ายและวางไว้ตามที่อยู่ที่ระบุในตัวถูกดำเนินการที่สอง ตัวอย่างเช่น:
pop dx - กู้คืนเนื้อหาของ dx register จากสแต็ก

7. คำสั่งเพิ่มเติม

เพิ่ม<операнд 1> , <операнд 2>
ADC<операнд 1> , <операнд 2>

ตั้งค่าสถานะสำหรับความเท่าเทียมกัน, สัญญาณของผลลัพธ์, การมีอยู่ของการบรรทุก, การมีอยู่ของการล้น

Ilo ไปยังคำสั่ง ADD เพิ่มตัวถูกดำเนินการสองตัว ผลลัพธ์จะถูกเขียนไปยังที่อยู่ของตัวถูกดำเนินการแรก คำสั่ง ADC จะเพิ่มตัวถูกดำเนินการสองตัวด้วย แต่ค่าที่เขียนในบิตพกพาที่กำหนดโดยคำสั่ง add ก่อนหน้าจะถูกเพิ่มเข้าไป

ในรูป 7 รายการ วิธีที่เป็นไปได้ตำแหน่งของเงื่อนไข โดยที่ a - ตัวถูกดำเนินการ - คำ b - ตัวถูกดำเนินการ - ไบต์

ต่อไปนี้คือตัวอย่างการเพิ่มตัวเลข 32 บิตสองตัว:

mov ขวาน value1
เพิ่มมูลค่า2, ax
mov ขวาน value1 + 2
ค่า adc2 + 2, ax

ตัวเลขดั้งเดิมจะอยู่ในหน่วยความจำหลักที่ address value1 และ value2 และผลลัพธ์จะถูกเขียนตาม address value1

8. คำสั่งการลบ

SUB<уменьшаемое-результат> , <вычитаемое>
SBB<уменьшаемое-результат>, <вычитаемое>

ตั้งค่าสถานะความเท่าเทียมกัน, สัญญาณของผลลัพธ์, การปรากฏตัวของเงินกู้, การปรากฏตัวของน้ำล้น

เมื่อการดำเนินการดำเนินการโดยคำสั่ง SUB เงินกู้จะไม่ถูกนำมาพิจารณา แต่โดยคำสั่ง SBB - จะถูกนำมาพิจารณา ข้อจำกัดเกี่ยวกับตำแหน่งของตัวถูกดำเนินการเหมือนกับคำสั่งเพิ่มเติม

9. คำสั่งเปลี่ยนเครื่องหมาย

NEG<операнд>
เครื่องหมายของตัวถูกดำเนินการจะกลับกัน

10. คำสั่งเพิ่มหน่วย

INC<операнд>
ค่าของตัวถูกดำเนินการจะเพิ่มขึ้นทีละหนึ่ง

11. คำสั่งลบหนึ่ง

ธ.ค.<операнд>
ค่าของตัวถูกดำเนินการจะลดลงหนึ่ง

12. คำสั่งเปรียบเทียบ

CMP<операнд 1> , < операнд 2>
การดำเนินการลบจะดำเนินการโดยไม่บันทึกผลลัพธ์และคุณลักษณะจะถูกตั้งค่าในบัญชีแยกประเภท

13. คำสั่งการคูณ

มูล<операнд>
IMUL<операнд>

ตั้งค่าสถานะการพกพาหรือโอเวอร์โฟลว์

ในคำสั่ง MUL ตัวเลขจะถูกคูณโดยไม่ต้องคำนึงถึงและตามคำสั่ง - IMUL โดยคำนึงถึงเครื่องหมาย (ในรหัสเสริม)

ในรูป 8 (โดยที่ a - ตัวถูกดำเนินการ - คำ b - ตัวถูกดำเนินการ - ไบต์) แสดงวิธีที่เป็นไปได้ในการวางปัจจัยและผลลัพธ์ (หนึ่งในปัจจัยจะอยู่ในทะเบียนสะสมเสมอ

ลองพิจารณาตัวอย่าง:
imul คำ ptr c

ที่นี่เนื้อหาของหน่วยความจำหลักตามที่อยู่ "ด้วย" ความยาวของคำจะถูกคูณด้วยเนื้อหาของขวานลงทะเบียน ส่วนล่างของผลลัพธ์ของการดำเนินการจะถูกเขียนไปยังการลงทะเบียน ax และส่วนบนก็เขียนไปยังการลงทะเบียน dx ด้วย

14. กองบัญชาการ

DIV<операнд-делитель>
IDIV<операнд-делитель>

คำสั่ง DIV ดำเนินการแบ่งโดยไม่ต้องทำบัญชี และด้วยคำสั่ง IDIV การแบ่งจะถูกเซ็นชื่อ (ในส่วนเสริมของสองส่วน)

ในรูป 9 แสดงวิธีที่เป็นไปได้ของการจ่ายเงินปันผล ตัวหาร และผลลัพธ์ (a - ตัวถูกดำเนินการ - คำ b - ตัวถูกดำเนินการ - ไบต์)

15. คำสั่งในการแปลงไบต์เป็นคำและคำ - เป็นคำคู่

CBW
CWD

โดยคำสั่ง CBW ตัวเลขจาก al จะถูกเขียนใหม่เป็น ax (การเสริมจะดำเนินการด้วยตัวเลขสัญลักษณ์) ในทำนองเดียวกัน ด้วยคำสั่ง CWD ตัวเลขจากขวานจะถูกเขียนใหม่เป็นสองรีจิสเตอร์ dx และ axe (dx: axe)

1.5. คำสั่งควบคุมการโอน

1. คำสั่งกระโดดแบบไม่มีเงื่อนไข

JMP<адрес перехода>

มีการดัดแปลงสามแบบขึ้นอยู่กับความยาวของส่วนที่อยู่:

  • สั้น - เมื่อย้ายไปยังที่อยู่ที่ระยะทาง -128 ... 127 ไบต์สัมพันธ์กับที่อยู่ของคำสั่งนี้ (ความยาวของส่วนที่อยู่คือ 1 ไบต์);
  • ใกล้ ptr - เมื่อย้ายไปยังที่อยู่ที่ระยะทาง Z2 Kbytes (-32768 ... 32767 ไบต์) สัมพันธ์กับที่อยู่ของคำสั่งนี้ (ความยาวของส่วนที่อยู่คือ 2 ไบต์);
  • far ptr - เมื่อย้ายไปยังที่อยู่ที่ระยะทางเกิน 32 Kbytes (ความยาวของส่วนที่อยู่คือ 4 ไบต์)

เมื่อระบุการข้ามไปยังคำสั่งก่อนคำสั่ง jump แอสเซมเบลอร์จะกำหนดระยะห่างของเครื่องหมายการข้ามและสร้างแอดเดรสของความยาวที่ต้องการ เมื่อระบุการเปลี่ยนไปยังส่วนต่อๆ ไปของโปรแกรม จำเป็นต้องใส่พอยน์เตอร์ให้สั้น ใกล้ ptr และ far ptr

ป้ายกำกับสามประเภทใช้เป็นที่อยู่ของคำสั่ง jump:

  • แต่)< имя >: nore (nore - คำสั่ง "no operation");
  • NS)< имя>ป้ายกำกับใกล้ (สำหรับการเปลี่ยนระหว่างส่วน);
  • ใน)<имя>label far (สำหรับการกระโดดนอกกลุ่ม)
  • a) jmp short b - ข้ามไปยังที่อยู่ b;
  • b) jmp - ข้ามไปยังที่อยู่ในการลงทะเบียน bx (ที่อยู่ถูกกำหนดทางอ้อม);
  • c) a: pore - คำอธิบายของเครื่องหมายการเปลี่ยนแปลง "a";
  • d) b label ใกล้ - คำอธิบายของป้ายกำกับการเปลี่ยนแปลง "b"

2. คำสั่งสาขาเงื่อนไข

<мнемоническая команда> <адрес перехода>
ตัวช่วยจำของคำสั่งกระโดดแบบมีเงื่อนไข:

  • JZ- เปลี่ยนเป็น "ศูนย์";
  • เจ- การเปลี่ยนแปลงโดย "เท่าเทียมกัน";
  • JNZ- เปลี่ยนเป็น "ไม่ใช่ศูนย์";
  • JNE- เปลี่ยนเป็น "ไม่เท่ากัน";
  • JL- เปลี่ยนเป็น "น้อย";
  • JNG, JLE- การเปลี่ยนแปลงโดย "น้อยกว่าหรือเท่ากับ";
  • JG- เปลี่ยนเป็น "มากกว่า";
  • JNL, JGE- การเปลี่ยนแปลงโดย "มากกว่าหรือเท่ากับ";
  • JA- เปลี่ยนเป็น "สูงกว่า" (ไม่ได้ลงนามเพิ่มเติม);
  • JNA, เจบีอี- การเปลี่ยนแปลงโดย "ไม่สูงกว่า" (ไม่ได้ลงนามอีกต่อไป);
  • เจบี- เปลี่ยนเป็น "ด้านล่าง" (ไม่ได้ลงชื่อน้อยกว่า);
  • JNB, แจ- เปลี่ยนเป็น "ไม่ต่ำกว่า" (ไม่ได้ลงนามไม่น้อย)

คำสั่งทั้งหมดมีฟิลด์แอดเดรสหนึ่งไบต์ ดังนั้น การผสมไม่ควรเกิน -128 ... 127 ไบต์ หากการกระจัดเกินขอบเขตที่กำหนดจะใช้เทคนิคพิเศษ: (อ่านในคู่มือ)

3. คำสั่งสำหรับจัดระเบียบการประมวลผลแบบวนรอบ

เนื้อหาของรีจิสเตอร์ถูกใช้เป็นตัวนับรอบในคำแนะนำการประมวลผลแบบวนทั้งหมด cx.

1) ทีมจัดวงจร

LOOP< адрес перехода >
ในแต่ละการดำเนินการ ลดเนื้อหาของรีจิสเตอร์ cx ทีละรายการและโอนการควบคุมไปยังที่อยู่ที่ระบุ ถ้า cx ไม่เท่ากับ 0:

start_loop:
; ... ตัวของวง ...
วนรอบ start_loop

บันทึก. หากโหลด 0 ลงในการลงทะเบียน cx ก่อนเริ่มการวนซ้ำ การวนซ้ำจะถูกดำเนินการ 35536 ครั้ง

2) คำสั่งให้ไปที่ตัวนับศูนย์

JCXZ<адрес перехода>

โอนการควบคุมไปยังที่อยู่ที่ระบุหากเนื้อหาของการลงทะเบียน cx เป็น 0 ตัวอย่างเช่น
mov cx, loop_count;เคาน์เตอร์โหลด
jcxz end_of_loop;เช็คมิเตอร์
start_loop:
; ... ตัวของวง ...
วนรอบ start_loop
end_of_loop:
...

3) คำสั่งในการจัดระเบียบลูปด้วยเงื่อนไข

LOOPE<адрес перехода>
LOOPNE<адрес перехода>

ลดเนื้อหาลงหนึ่งรายการและโอนการควบคุมไปยังที่อยู่ที่ระบุ โดยที่เนื้อหาของ cx ไม่เป็นศูนย์ แต่ LOOPE ยังต้องการแฟล็ก "เท่ากับ" และ LOOPNE - "ไม่เท่ากัน" ที่สร้างโดยคำสั่งเปรียบเทียบ ตัวอย่างเช่น

mov cx, loop_count; เคาน์เตอร์โหลด
jcxz end_of_loop; เช็คมิเตอร์
start_loop:
; ... ตัวของวง ...
cmp อัล 100; การตรวจสอบเนื้อหาของal
loopne start_loop; กลับไปที่ลูปถ้า cx0 และ al100
end_of_loop: ...

4. คำสั่งเรียกรูทีนย่อย

1) คำสั่งเรียกขั้นตอน

เรียก<адрес процедуры>

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

  • a) หากขั้นตอนถูกลบไม่เกิน -128 ... 127 ไบต์ก็ไม่จำเป็นต้องมีคำแนะนำพิเศษ
  • b) หากขั้นตอนถูกลบภายใน 32 กิโลไบต์ก่อนที่อยู่ของขั้นตอนคุณต้องระบุใกล้ ptr
  • c) ถ้าโพรซีเดอร์รูทีนย่อยถูกลบมากกว่า 32 กิโลไบต์ ดังนั้นจะต้องเขียน far ptr ก่อนแอดเดรสของโพรซีเดอร์

ตัวอย่างเช่น:

โทรใกล้ ptr p - โทรรูทีนย่อย "p"
ข้อความของขั้นตอนควรอยู่ในรูปแบบ:
< имя процедуры>proc< указатель удаленности>
...เนื้อความของขั้นตอน ...
<имя процедуры>จบ

ในที่นี้ ตัวระบุระยะทางยังทำหน้าที่กำหนดความยาวของที่อยู่ที่ใช้เมื่ออ้างถึงขั้นตอน: ใกล้ - เมื่อใช้ที่อยู่แบบสองไบต์ ไกล - เมื่อใช้ที่อยู่แบบสี่ไบต์

2) การควบคุมการคืนคำสั่ง

RET [<число>]

แสดงที่อยู่ผู้ส่งกลับจากสแต็กและโอนการควบคุมไปยังที่อยู่ที่ระบุ

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

1.6. คำสั่งประมวลผลสตริง

คำสั่งการประมวลผลสตริงใช้เพื่อวนซ้ำลำดับขององค์ประกอบที่มีความยาว I หรือ 2 ไบต์ ในกรณีนี้ ตัวถูกดำเนินการจะถูกระบุโดยใช้คู่ลงทะเบียน: DS: SI - ต้นทาง, ES: DI - ปลายทาง คำสั่งมีการแก้ไขที่อยู่ของตัวถูกดำเนินการตามแฟล็กทิศทาง D: 1 - ลดที่อยู่ตามความยาวขององค์ประกอบ 0 - เพิ่มที่อยู่ตามความยาวขององค์ประกอบ การแก้ไขจะดำเนินการหลังจากดำเนินการเสร็จสิ้น

การตั้งค่าที่ต้องการของแฟล็กทิศทางจะดำเนินการโดยคำสั่งพิเศษ:

โรคติดต่อทางเพศสัมพันธ์- ตั้งธงทิศทางเป็นหนึ่ง
CLD- รีเซ็ตธงทิศทางเป็นศูนย์

1) คำสั่งโหลดบรรทัด LODS

คำสั่งโหลดไบต์ลงใน AL หรือคำลงใน AX การลงทะเบียน DS ใช้เพื่อระบุตัวถูกดำเนินการ: SI

2) คำสั่งให้เขียนบรรทัด STOS

STOSB(เขียนไบต์)
STOSW(บันทึกคำ)

เขียนเนื้อหาของ AL หรือ AX ไปยังหน่วยความจำหลักตามลำดับ การลงทะเบียน ES: DI ใช้เพื่อระบุตัวถูกดำเนินการ

3) โอนคำสั่งMOVS

MOVSB(การถ่ายโอนไบต์)
MOVSW(คำไปข้างหน้า)
ถ่ายโอนองค์ประกอบสตริงจากพื้นที่ที่ลงทะเบียน DS: SI ไปยังพื้นที่ที่ลงทะเบียน ES: DI

4) คำสั่งสแกนเส้น SCAS

SCASB(การค้นหาไบต์)
SCASW(ค้นหาคำ).

ตามคำสั่ง เนื้อหาของการลงทะเบียน AL หรือ AX จะถูกเปรียบเทียบกับรายการโฆษณาที่ระบุโดยการลงทะเบียน DS: SI และการตั้งค่าสถานะจะถูกตั้งค่าตามผลลัพธ์ - AL หรือ -AX

5) คำสั่งเปรียบเทียบสตริง CMPS

CMPSB(เปรียบเทียบไบต์)
CMPSW(เปรียบเทียบคำ)

องค์ประกอบของสตริงที่ระบุโดยคู่ลงทะเบียน DS: SI และ ES: DI ถูกเปรียบเทียบและตั้งค่าสถานะตามผลลัพธ์ -

6) คำนำหน้าคำสั่งทำซ้ำ

ตัวแทน<команда>

ช่วยให้คุณสามารถจัดระเบียบการทำซ้ำของคำสั่ง CX ที่ระบุครั้ง ตัวอย่างเช่น:

ตัวแทน stosb

ฟิลด์ที่เขียนโดยคู่ของรีจิสเตอร์ ES: DI ของความยาว CX นั้นเต็มไปด้วยเนื้อหาของ AL

7) คำนำหน้าคำสั่ง "ทำซ้ำจนกว่าจะเท่ากัน" และ "ทำซ้ำจนกว่าจะไม่เท่ากัน"

REPE< команда >
REPNE< команда >

คำสั่งนำหน้าใช้ร่วมกับคำสั่ง CMPS และ SCAS คำนำหน้า REPE หมายถึงการทำซ้ำจนกว่าเนื้อหาของการลงทะเบียน CX เท่ากับศูนย์และค่าของการตั้งค่าสถานะศูนย์เท่ากับหนึ่ง และ REPNE หมายถึงการทำซ้ำจนกว่าเนื้อหาของการลงทะเบียน CX จะไม่เท่ากับศูนย์และค่าของ ค่าสถานะศูนย์คือศูนย์

1.7. คำสั่งจัดการบิต

1. คำสั่งเชิงตรรกะ

  • ไม่<операнд>- ตรรกะไม่;
  • และ<операнд 1>, <операнд 2>- ligic และ;
  • หรือ<операнд 1>, <операнд 2>- ตรรกะหรือ;
  • XOR<операнд 1>, <операнд 2>- พิเศษ OR;
  • ทดสอบ<операнд 1>, <операнд 2>- และไม่ต้องบันทึกผล

ตัวถูกดำเนินการคือไบต์หรือคำ

ตัวอย่าง. แยกบิตแรกออกจากตัวเลขใน AL:
และอัล 10000000B

2. คำสั่ง Shift

<код операции> <операнд>, <счетчик>
ตัวนับถูกเขียนลงในการลงทะเบียน CL หากตัวนับเป็น 1 ก็สามารถเขียนไปยังคำสั่งได้

รหัสคำสั่ง Shift

  • SAL- เลขคณิตกะซ้าย
  • SHL- กะซ้ายตรรกะ;
  • SAR- เลื่อนไปทางเลขคณิตที่ถูกต้อง
  • SHR- กะขวาเชิงตรรกะ
  • ROL- เลื่อนไปทางซ้ายเป็นวงกลม
  • ROR- เลื่อนไปทางขวาเป็นวงกลม
  • RCL- เลื่อนไปทางซ้ายด้วยธงพกพา
  • RCR- เลื่อนไปทางขวาพร้อมกับถือแฟล็ก

ตัวอย่าง. คูณตัวเลขใน AX ด้วย 10:

mov bx, ขวาน
shl ขวาน 1
shl ขวาน 1
เพิ่มขวาน bx
shl ขวาน 1

1.8. คำสั่ง I/O

การแลกเปลี่ยนข้อมูลกับสภาพแวดล้อมภายนอกดำเนินการโดยใช้คำสั่งต่อไปนี้:

  • ใน<регистр>, <порт> (อินพุตจากพอร์ตเพื่อลงทะเบียน)
  • ใน<регистр >, DX(อินพุตจากพอร์ตจำนวนที่ระบุในการลงทะเบียน DX ในการลงทะเบียน);
  • ออก<порт>, <регистр> (ส่งออกเนื้อหาของการลงทะเบียนไปยังพอร์ต)
  • ออก DX,<регистр> (ส่งออกเนื้อหาของรีจิสเตอร์ไปยังพอร์ตซึ่งระบุจำนวนในการลงทะเบียน DX)

ในฐานะรีจิสเตอร์ คุณสามารถระบุ AL หรือ AX (ตามลำดับ ไบต์หรือสองไบต์จะได้รับการประมวลผล) พอร์ตถูกระบุด้วยบางส่วน อุปกรณ์ภายนอก (0...255).

อย่างไรก็ตาม เมื่อจัดระเบียบ I / O นอกเหนือจากการดำเนินการแล้วจำเป็นต้องดำเนินการเพิ่มเติมหลายประการเช่นเพื่อตรวจสอบความพร้อมของอุปกรณ์ ในเรื่องนี้ โปรแกรมมาตรฐานสำหรับการจัดระเบียบอินพุต-เอาท์พุตได้รับการพัฒนาสำหรับอุปกรณ์ทั่วไป ซึ่งเรียกโดยคำสั่ง int 21h ขัดจังหวะ

ตารางที่ 1 แสดงรายการฟังก์ชันหลักที่ใช้โดยรูทีน I / O และรหัส ต้องส่งรหัสฟังก์ชันไปยังรูทีนย่อยในการลงทะเบียน AH

ตัวอย่าง:

  • ก) mov ah, 1; ฟังก์ชั่นหมายเลข
    int 21h; การป้อนอักขระ: อักขระใน AL
  • b) mov ah, 2; ฟังก์ชั่นหมายเลข
    mov dl "เอ"
    int 21h; อักขระเอาต์พุตจากDL
  • c) ลี dx, STRING; ที่อยู่บัฟเฟอร์อินพุต
    mov ah, 0Ah; ฟังก์ชั่นหมายเลข
    int 21h; อินพุตบรรทัด: ในไบต์ที่สองของบัฟเฟอร์ - หมายเลข
    ...; ป้อนอักขระแล้วอักขระในบัฟเฟอร์
    STRING db 50, 50 ซ้ำ (?)
  • ง) ลี dx, ผงชูรส; ที่อยู่ของสตริงเอาต์พุต
    mov อ่า 9; ฟังก์ชั่นหมายเลข
    int 21h; เอาต์พุตสาย
    ...
    ผงชูรส db "ตัวอย่างผลลัพธ์", 13, 10, "$"

การมอบหมายงานห้องปฏิบัติการครั้งที่ 3

ด้านล่างนี้เป็นตัวอย่างของข้อความของโปรแกรมที่ในภาษาแอสเซมบลี กำหนดองค์ประกอบที่มีค่าสูงสุดในอาร์เรย์ที่กำหนด

SGSTACK SEGMENT PARA กอง "กอง"
DB 32 DUP (?)
SGSTACK สิ้นสุด

กลุ่มข้อมูล PARA สาธารณะ "ข้อมูล"
แม็กซ์ DW?
ARRAY DW 10H, 20H, 30H, 0D0H, 0A0H
ข้อมูลสิ้นสุด

รหัสส่วนงาน PARA สาธารณะ "รหัส"
สมมติ CS: รหัส DS: DATA, SS: SGSTACK

เริ่ม: MOV AX, ข้อมูล; อัปโหลดไปยังDS
MOV DS, AX; ตัวเลือกส่วนข้อมูล
LEA BX, อาร์เรย์; โหลดที่อยู่เริ่มต้นของอาร์เรย์ลงในBX
MOV CX, 4; เริ่มต้นเคาน์เตอร์
MOV ขวาน,; เริ่มต้นค่าเริ่มต้นของmax

รอบ: เพิ่ม BX, 2; ไปที่องค์ประกอบถัดไปของอาร์เรย์
CMP, ขวาน; เปรียบเทียบสองค่า
เจบีอี บี; กระโดดถ้าเท่ากันหรือต่ำกว่า
MOV ขวาน,; ให้มีค่ามากขึ้น
พ.ศ. : LOOP CYCLE; ตรวจสอบการออกจากลูป (--CX with CX = 0)
MOV MAX, ขวาน; รักษามูลค่าสูงสุด

ทางออก: XOR AL, AL; ออกจาก OS
MOV AH, 4CH
INT 21H
รหัส ENDS
สิ้นสุด START

สั่งงาน

ในการปฏิบัติงานในห้องปฏิบัติการ คุณต้อง:

  1. รับงานมอบหมายจากครูจากตาราง
  2. สร้างโปรแกรมตามตัวเลือกที่กำหนด
  3. รับไฟล์กับ ข้อความต้นฉบับโปรแกรมในรูปแบบ EXE และ COM
  4. แปล ดีบักโปรแกรม ตรวจสอบรายชื่อโปรแกรม
  5. สร้างไฟล์ปฏิบัติการ ตรวจสอบแผนที่โหลด (ลำดับของเซ็กเมนต์ ขนาด และที่อยู่ที่เกี่ยวข้อง)
  6. เรียกใช้โปรแกรมภายใต้ดีบักเกอร์
  7. ส่งรายงาน

ในการเขียนโปรแกรมแอสเซมบลี เราจำเป็นต้องรู้ว่ามีรีจิสเตอร์ตัวประมวลผลใดบ้างและใช้งานอย่างไร โปรเซสเซอร์ทั้งหมดของสถาปัตยกรรม x86 (แม้แต่ multi-core ขนาดใหญ่และซับซ้อน) เป็นลูกหลานที่อยู่ห่างไกลจาก Intel 8086 โบราณและเข้ากันได้กับสถาปัตยกรรมของมัน ซึ่งหมายความว่าโปรแกรมประกอบ 8086 จะทำงานบนโปรเซสเซอร์ x86 ที่ทันสมัยทั้งหมด

การลงทะเบียนภายในทั้งหมดของโปรเซสเซอร์ Intel 8086 เป็นแบบ 16 บิต:

โดยรวมแล้ว โปรเซสเซอร์ประกอบด้วยรีจิสเตอร์ที่เข้าถึงได้ของซอฟต์แวร์ 12 รายการ เช่นเดียวกับแฟล็กรีจิสเตอร์ (FLAGS) และตัวชี้คำสั่ง (IP)

ทะเบียนวัตถุประสงค์ทั่วไป (RON) AX, BX, CX และ DX ใช้เพื่อเก็บข้อมูลและดำเนินการทางคณิตศาสตร์และตรรกะต่างๆ นอกจากนี้ แต่ละรีจิสเตอร์เหล่านี้ยังแบ่งออกเป็น 2 ส่วนคือ 8 บิต ซึ่งสามารถใช้เป็นรีจิสเตอร์ 8 บิตได้ (AH, AL, BH, BL, CH, CL, DH, DL) ส่วนล่างของทะเบียนมีตัวอักษร L อยู่ในชื่อ (จากคำว่า ต่ำ) และ H ที่เก่ากว่า (จากคำว่า สูง). บางคำสั่งใช้รีจิสเตอร์เฉพาะโดยปริยาย ตัวอย่างเช่น CX สามารถทำหน้าที่เป็นตัวนับลูปได้

การลงทะเบียนดัชนีมีไว้สำหรับจัดเก็บดัชนีเมื่อทำงานกับอาร์เรย์ เอสไอ ( ดัชนีแหล่งที่มา) มีดัชนีต้นทางและ DI ( ดัชนีปลายทาง) - ดัชนีตัวรับ แม้ว่าจะสามารถใช้เป็นรีจิสเตอร์เอนกประสงค์ได้

การลงทะเบียนตัวชี้ BP และ SP ใช้สำหรับการจัดการสแต็ก บีพี ( ตัวชี้ฐาน) ช่วยให้คุณทำงานกับตัวแปรในสแต็กได้ นอกจากนี้ยังสามารถใช้เพื่อวัตถุประสงค์อื่นได้อีกด้วย เอสพี ( ตัวชี้สแต็ค) ชี้ไปที่ด้านบนของสแต็ก มันถูกใช้โดยคำสั่งที่จัดการสแต็ค (ผมจะพูดถึงรายละเอียดในส่วนที่แยกต่างหากของหลักสูตรฝึกอบรม)

การลงทะเบียนเซกเมนต์ซีเอส ( ส่วนรหัส), ดีเอส ( ส่วนข้อมูล), NS ( กองกอง) และ ES ( ส่วนที่ปรับปรุงแล้ว) ได้รับการออกแบบมาเพื่อให้การระบุที่อยู่ของกลุ่ม รหัสอยู่ในกลุ่มรหัส ข้อมูลอยู่ในกลุ่มข้อมูล กองอยู่ในกลุ่มกองซ้อน และมีกลุ่มข้อมูลเพิ่มเติม ที่อยู่จริงได้มาจากการย้ายเนื้อหาของเซ็กเมนต์รีจิสเตอร์ 4 บิตไปทางซ้ายและเพิ่มออฟเซ็ต (แอดเดรสสัมพัทธ์ภายในเซ็กเมนต์) เข้าไป สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดที่อยู่ของกลุ่ม โปรดดูส่วนที่ 31

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

ตัวชี้คำสั่งไอพี ( ตัวชี้คำสั่ง) มีที่อยู่ของคำสั่ง (ในส่วนของรหัส) คุณไม่สามารถแก้ไขเนื้อหาได้โดยตรง แต่ตัวประมวลผลดำเนินการเอง เมื่อดำเนินการคำสั่งปกติ ค่า IP จะเพิ่มขึ้นตามขนาดของคำสั่งที่ดำเนินการ นอกจากนี้ยังมีคำสั่งโอนที่เปลี่ยนค่า IP เพื่อให้สามารถแยกสาขาภายในโปรแกรมได้

ลงทะเบียนธงธงประกอบด้วย แต่ละบิต: ธงควบคุมและสัญญาณผลลัพธ์ แฟล็กควบคุมเปลี่ยนโหมดโปรเซสเซอร์:

  • NS ( ทิศทาง) - ธงทิศทาง ควบคุมทิศทางของการประมวลผลบรรทัดข้อมูล: DF = 0 - จากที่อยู่ที่ต่ำกว่าไปยังที่อยู่ที่สูงกว่า DF = 1 - จากที่อยู่ที่สูงกว่าไปยังที่อยู่ต่ำกว่า (สำหรับคำสั่งสตริงพิเศษ)
  • ผม ( ขัดจังหวะ) - แฟล็กขัดจังหวะ หากค่าของบิตนี้เป็น 1 แสดงว่าอินเตอร์รัปต์ถูกเปิดใช้งาน มิฉะนั้น จะถูกปิดใช้งาน
  • NS ( กับดัก) - แฟล็กการติดตาม ใช้โดยดีบักเกอร์เพื่อทำตามขั้นตอนในโปรแกรม

สัญญาณของผลลัพธ์ถูกกำหนดหลังจากการดำเนินการของคำสั่งเลขคณิตและตรรกะ:

  • NS ( เข้าสู่ระบบ) - เครื่องหมายของผลลัพธ์ เท่ากับเครื่องหมายบิตของผลการดำเนินการ ถ้าเท่ากับ 1 ผลลัพธ์จะเป็นลบ
  • ซี ( ศูนย์) เป็นแฟล็กผลลัพธ์ที่เป็นโมฆะ ZF = 1 ถ้าผลลัพธ์เป็นศูนย์
  • NS ( ความเท่าเทียมกัน) เป็นสัญญาณของความสม่ำเสมอของผลลัพธ์
  • ค ( พก) - ถือธง. CF = 1 หากในระหว่างการบวก / การลบ มีการพกพา / ยืมจากบิตที่สำคัญที่สุด ในกะ ให้เก็บค่าของบิตที่จะดึงออกมา
  • NS ( ตัวช่วย) - ธงพกพาเพิ่มเติม ใช้ในการดำเนินการกับหมายเลข BCD ที่บรรจุไว้
  • โอ ( ล้น) - ธงล้น CF = 1 ถ้าผลลัพธ์อยู่นอกช่วง

อย่ากังวลหากมีบางสิ่งที่ดูสับสน จากคำอธิบายเพิ่มเติมจะเห็นได้ชัดว่าอะไรคืออะไรและใช้อย่างไร 🙂