สิ่งแรกที่คุณต้องการคือไฟล์แบบนี้ นี่คือฐานข้อมูลคำแนะนำสำหรับโปรเซสเซอร์ x86 ที่ใช้โดยแอสเซมเบลอร์ NASM (ซึ่งฉันช่วยเขียนแม้ว่าจะไม่ใช่ชิ้นส่วนที่แปลคำสั่งจริง) ให้เลือกบรรทัดโดยพลการจากฐานข้อมูล:
ADD rm32,imm8 [mi: hle o32 83 /0 ib,s] 386,LOCK
ADDสิ่งที่หมายถึงนี้ก็คือว่ามันอธิบายถึงการเรียนการสอน คำสั่งนี้มีหลายรูปแบบและชุดคำสั่งเฉพาะที่อธิบายไว้ที่นี่เป็นชุดตัวเลือกที่ทำการลงทะเบียน 32 บิตหรือที่อยู่หน่วยความจำและเพิ่มค่า 8 บิตทันที (เช่นค่าคงที่รวมอยู่ในคำสั่งโดยตรง) ตัวอย่างคำสั่งแอสเซมบลีที่จะใช้รุ่นนี้คือ:
add eax, 42
ตอนนี้คุณต้องป้อนข้อความของคุณและแยกมันเป็นคำแนะนำและตัวถูกดำเนินการแต่ละรายการ สำหรับคำสั่งข้างต้นนี้อาจส่งผลให้โครงสร้างที่มีคำสั่งADDและอาร์เรย์ของตัวถูกดำเนินการ (อ้างอิงถึงการลงทะเบียนEAXและค่า42) เมื่อคุณมีโครงสร้างนี้คุณจะรันฐานข้อมูลคำสั่งและค้นหาบรรทัดที่ตรงกับชื่อคำสั่งและประเภทของตัวถูกดำเนินการ หากคุณไม่พบคู่ที่ตรงกันนั่นเป็นข้อผิดพลาดที่ต้องแสดงต่อผู้ใช้ ("การรวมกันของ opcode และตัวถูกดำเนินการ" หรือคล้ายกันคือข้อความปกติ)
เมื่อเราได้รับบรรทัดจากฐานข้อมูลเราจะดูคอลัมน์ที่สามซึ่งสำหรับคำสั่งนี้คือ:
[mi: hle o32 83 /0 ib,s]
นี่เป็นชุดคำสั่งที่อธิบายวิธีสร้างคำสั่งรหัสเครื่องที่ต้องการ:
- นี่
miคือคำอธิบายของตัวถูกดำเนินการ: ตัวถูกดำเนินการหนึ่งตัวmodr/m(ลงทะเบียนหรือหน่วยความจำ) (ซึ่งหมายความว่าเราจะต้องผนวกmodr/mไบต์ต่อท้ายคำสั่งซึ่งเราจะมาภายหลัง) และหนึ่งคำสั่งทันที (ซึ่งจะ นำมาใช้ในคำอธิบายของการเรียนการสอน)
hleถัดไปคือ นี่เป็นการระบุวิธีที่เราจัดการส่วนนำหน้า "ล็อค" เราไม่ได้ใช้ "ล็อค" ดังนั้นเราจึงไม่สนใจ
o32ถัดไปคือ สิ่งนี้บอกเราว่าหากเรากำลังรวบรวมรหัสสำหรับรูปแบบเอาต์พุตขนาด 16 บิตคำสั่งนั้นจำเป็นต้องมีคำนำหน้าแทนที่ขนาดตัวถูกดำเนินการ หากเราผลิตเอาต์พุต 16 บิตเราจะผลิตคำนำหน้าทันที ( 0x66) แต่ฉันจะสมมติว่าเราไม่ได้ดำเนินการต่อไป
83ถัดไปคือ นี่คือไบต์ที่แท้จริงในฐานสิบหก เราส่งออกมัน
/0ถัดไปคือ สิ่งนี้ระบุบิตพิเศษบางอย่างที่เราต้องการใน modr / m bytem และทำให้เราสร้างมันขึ้นมา modr/mไบต์จะใช้ในการลงทะเบียนการเข้ารหัสหรือการอ้างอิงหน่วยความจำทางอ้อม เรามีตัวถูกดำเนินการเช่นเดียวกับการลงทะเบียน รีจิสเตอร์มีหมายเลขซึ่งระบุไว้ในไฟล์ข้อมูลอื่น :
eax REG_EAX reg32 0
เราตรวจสอบว่าreg32เห็นด้วยกับขนาดที่ต้องการของคำสั่งจากฐานข้อมูลดั้งเดิม (ใช่) 0เป็นจำนวนที่ลงทะเบียน modr/mไบต์เป็นโครงสร้างข้อมูลที่ระบุโดยหน่วยประมวลผลที่มีลักษณะเช่นนี้
(most significant bit)
2 bits mod - 00 => indirect, e.g. [eax]
01 => indirect plus byte offset
10 => indirect plus word offset
11 => register
3 bits reg - identifies register
3 bits rm - identifies second register or additional data
(least significant bit)
เพราะเรากำลังทำงานกับการลงทะเบียนที่เขตข้อมูลmod0b11
regข้อมูลเป็นจำนวนของการลงทะเบียนที่เรากำลังใช้,0b000
- เนื่องจากมีเพียงหนึ่งการลงทะเบียนในคำสั่งนี้เราจึงต้องกรอกข้อมูลลงใน
rmฟิลด์ ว่าข้อมูลอะไรเป็นพิเศษที่ระบุไว้ใน/0เป็นดังนั้นเราใส่ที่อยู่ในสนามrm0b000
modr/mไบต์ดังนั้นจึงเป็นเรื่องหรือ0b11000000 0xC0เราส่งออกสิ่งนี้
ib,sถัดไปคือ นี้ระบุไบต์ทันทีที่ลงนาม เราดูตัวถูกดำเนินการและทราบว่าเรามีค่าทันที เราแปลงเป็นไบต์ที่ลงนามแล้วส่งออก ( 42=> 0x2A)
0x83 0xC0 0x2Aการเรียนการสอนการประกอบที่สมบูรณ์ดังนั้นจึงเป็น: ส่งไปยังโมดูลเอาต์พุตของคุณพร้อมกับทราบว่าไม่มีไบต์ใดที่ประกอบด้วยการอ้างอิงหน่วยความจำ
ทำซ้ำสำหรับทุกคำสั่ง ติดตามป้ายกำกับเพื่อให้คุณรู้ว่าต้องใส่อะไรเมื่อมีการอ้างอิง เพิ่มเครื่องมืออำนวยความสะดวกสำหรับแมโครและคำสั่งที่ส่งผ่านไปยังโมดูลเอาต์พุตไฟล์อ็อบเจ็กต์ของคุณ และนี่คือวิธีการที่แอสเซมเบลอร์ทำงาน