Ja, opN steht für den N-ten Operanden. Ein Operand ist meistens entweder
- ein Register (z.B. eAX, AL usw.)
- eine direkt (=immediate) auf den OP-Code folgende Konstante im Code (imm8, imm16, imm32)
- ein mod-R/M-Byte – eine auf konfuse Weise kodierte Kombination aus einem Register (r) und einer Adresse (m wie Memory) (in der Tabelle gekennzeichnet durch r/m8
, r16/32
, r/m16/32
etc.)
Die Sache mit dem mod-R/M-Byte zu verstehen, hat mich damals am meisten Zeit gekostet. Eine wirkliche Erklärung habe ich dazu nicht gefunden, aber immerhin diese
Übersicht¹, und daraus habe ich es mir dann zusammengereimt. Oben steht das
Ziel der Operation (immer Register), links die
Quelle (Register, oder Adresse).
Wenn z.B. im Register
EBX
eine Speicher-Adresse steht, und du den an dieser Adresse stehenden Wert in das Register
EAX
kopieren willst (als Mnemonic:
MOV EAX, [EBX]
²), so lautet der OP-Code dafür:
89 03
. Das erste Byte ist die Instruction
MOV
, das zweite Byte ist das mod-R/M-Byte für „EAX ← [EBX]“ (siehe Tabelle).
MOV EAX, EBX
(ohne eckige Klammern (!), also direkte Kopie des Register-Inhaltes) wäre hingegen
89 C3
.
¹ gerade jetzt sehe ich, dass das gleiche auch unten auf der anderen Seite steht...
² die eckigen Klammern sind bekanntlich der Dereferenzierungs-Operator, das Assembler-Äquivalent zu
Wert^
in Delphi