สิ่งแรกที่คุณต้องการคือไฟล์แบบนี้ นี่คือฐานข้อมูลคำแนะนำสำหรับโปรเซสเซอร์ 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)
เพราะเรากำลังทำงานกับการลงทะเบียนที่เขตข้อมูลmod
0b11
reg
ข้อมูลเป็นจำนวนของการลงทะเบียนที่เรากำลังใช้,0b000
- เนื่องจากมีเพียงหนึ่งการลงทะเบียนในคำสั่งนี้เราจึงต้องกรอกข้อมูลลงใน
rm
ฟิลด์ ว่าข้อมูลอะไรเป็นพิเศษที่ระบุไว้ใน/0
เป็นดังนั้นเราใส่ที่อยู่ในสนามrm
0b000
modr/m
ไบต์ดังนั้นจึงเป็นเรื่องหรือ0b11000000
0xC0
เราส่งออกสิ่งนี้
ib,s
ถัดไปคือ นี้ระบุไบต์ทันทีที่ลงนาม เราดูตัวถูกดำเนินการและทราบว่าเรามีค่าทันที เราแปลงเป็นไบต์ที่ลงนามแล้วส่งออก ( 42
=> 0x2A
)
0x83 0xC0 0x2A
การเรียนการสอนการประกอบที่สมบูรณ์ดังนั้นจึงเป็น: ส่งไปยังโมดูลเอาต์พุตของคุณพร้อมกับทราบว่าไม่มีไบต์ใดที่ประกอบด้วยการอ้างอิงหน่วยความจำ
ทำซ้ำสำหรับทุกคำสั่ง ติดตามป้ายกำกับเพื่อให้คุณรู้ว่าต้องใส่อะไรเมื่อมีการอ้างอิง เพิ่มเครื่องมืออำนวยความสะดวกสำหรับแมโครและคำสั่งที่ส่งผ่านไปยังโมดูลเอาต์พุตไฟล์อ็อบเจ็กต์ของคุณ และนี่คือวิธีการที่แอสเซมเบลอร์ทำงาน