Разработка компилятора ассемблера для процессора i80386
Написание компилятора ассемблера сводиться к выполнению следующих шагов:
Парсер языка - дело не такое уж и сложное. Сделаем для этого класс CParser.
Другое дело процесс компиляции. Для этого компилятор по данным парсера должен перелопатить кучу таблиц перевода мнемокодов в машинные коды. Таблицы приведены ниже.
1. Операции над целыми числами
Команды пересылки данных
Мнемокод | Операнд | Код | MOV | r/m, reg | 100010dw | modregr/m | MOV | r/m, imm | 1100011w | mod000r/m | data | MOV | reg, imm | 1011wreg | data | MOV | acc, mem | 101000dw | addr | MOV | r/m, seg | 100011d0 | modsegr/m | MOV | reg32, sys | 00001111 | 00100tdg | 11sysreg | XCHG | r/m, reg | 1000011w | modregr/m | XCHG | acc, reg16/32 | 10010reg | PUSH | r/m16/32 | 11111111 | mod110r/m | PUSH | reg16/32 | 01010reg | PUSH | seg (только cs, ds, ss, es) | 00seg110 | PUSH | seg | 00001111 | 10seg000 | PUSH | imm | 011010s0 | data | POP | r/m16/32 | 10001111 | mod110r/m | POP | reg16/32 | 01011reg | POP | seg (только cs, ds, ss, es) | 00seg111 | POP | seg | 00001111 | 10seg001 | PUSHA | - | 01100000 | PUSHAD | - | 01100000 | POPA | - | 01100001 | POPAD | - | 01100001 | IN | acc, imm8 | 1110010w | data | IN | acc, DX | 1110110w | OUT | acc, imm8 | 1110011w | data | OUT | acc, DX | 1110011w | MOVSX | reg16/32, r/m8 | 00001111 | 1011111w | modregr/m | MOVSX | reg32, r/m16 | 00001111 | 1011111w | modregr/m | MOVZX | reg16/32, r/m8 | 00001111 | 1011011w | modregr/m | MOVZX | reg32, r/m16 | 00001111 | 1011011w | modregr/m | XLAT | - | 11010111 | XLATB | - | 11010111 | LEA | reg16/32, mem16/32 | 10001101 | modregr/m (только для mod != 11) | LDS | reg16/32, mem16/32 | 11000101 | modregr/m (только для mod != 11) | LES | reg16/32, mem16/32 | 11000100 | modregr/m (только для mod != 11) | LFS | reg16/32, mem16/32 | 00001111 | 10110100 | modregr/m (только для mod != 11) | LGS | reg16/32, mem16/32 | 00001111 | 10110101 | modregr/m (только для mod != 11) | LSS | reg16/32, mem16/32 | 00001111 | 10110010 | modregr/m (только для mod != 11) |
---|
Команды арифметических операций
Мнемокод | Операнд | Код | ADD | r/m, reg | 000000dw | modregr/m | ADD | acc, imm | 0000010w | data | ADD | r/m, imm | 100000sw | mod000r/m | data | ADC | r/m, reg | 000100dw | modregr/m | ADC | acc, imm | 0001010w | data | ADC | r/m, imm | 100000sw | mod010r/m | data | SUB | r/m, reg | 001010dw | modregr/m | SUB | acc, imm | 0010110w | data | SUB | r/m, imm | 100000sw | mod101r/m | data | SBB | r/m, reg | 000110dw | modregr/m | SBB | acc, imm | 0001110w | data | SBB | r/m, imm | 100000sw | mod011r/m | data | CMP | r/m, reg | 001110dw | modregr/m | CMP | acc, imm | 0011110w | data | CMP | r/m, imm | 100000sw | mod111r/m | data | MUL | r/m | 1111011w | mod100r/m | IMUL | r/m | 1111011w | mod101r/m | IMUL | reg16/32, r/m16/32 | 00001111 | 10101111 | mоdregr/m | IMUL | reg16/32, r/m16/32, imm16/32 | 011010s1 | mоdregr/m | data | DIV | r/m | 1111011w | mod110r/m | IDIV | r/m | 1111011w | mod111r/m | CBW | - | 11010101 | CWDE | - | 11010101 | CWD | - | 10011001 | CDQ | - | 10011001 | AAA | - | 00110111 | AAS | - | 00111111 | AAM | - | 11010100 00001010 | AAD | - | 11010101 00001010 | DAA | - | 00100111 | DAS | - | 00101111 | INC | r/m | 1111111w | mod000r/m | INC | reg16/32 | 01000reg | DEC | r/m | 1111111w | mod001r/m | DEC | reg16/32 | 01001reg | NEG | r/m | 1111011w | mod011r/m |
---|
Команды логических операций и сдвигов
Мнемокод | Операнд | Код | AND | r/m, reg | 001000dw | modregr/m | AND | acc, imm | 0010010w | data | AND | r/m, imm | 100000sw | mod100r/m | data | OR | r/m, reg | 000010dw | modregr/m | OR | acc, imm | 0000110w | data | OR | r/m, imm | 100000sw | mod001r/m | data | XOR | r/m, reg | 001100dw | modregr/m | XOR | acc, imm | 0011010w | data | XOR | r/m, imm | 100000sw | mod110r/m | data | NOT | r/m | 1111011w | mod010r/m | TEST | r/m, reg | 1000010w | modregr/m | TEST | acc, imm | 1010100w | data | TEST | r/m, imm | 1111011w | mod000r/m | data | SAL | r/m, 1 | 1101000w | mod100r/m | SAL | r/m, CL | 1101001w | mod100r/m | SAL | r/m, imm8 | 1100000w | mod100r/m | data | SAR | r/m, 1 | 1101000w | mod111r/m | SAR | r/m, CL | 1101001w | mod111r/m | SAR | r/m, imm8 | 1100000w | mod111r/m | data | SHL | r/m, 1 | 1101000w | mod100r/m | SHL | r/m, CL | 1101001w | mod100r/m | SHL | r/m, imm8 | 1100000w | mod100r/m | data | SHR | r/m, 1 | 1101000w | mod101r/m | SHR | r/m, CL | 1101001w | mod101r/m | SHR | r/m, imm8 | 1100000w | mod101r/m | data | ROL | r/m, 1 | 1101000w | mod000r/m | ROL | r/m, CL | 1101001w | mod000r/m | ROL | r/m, imm8 | 1100000w | mod000r/m | data | ROR | r/m, 1 | 1101000w | mod001r/m | ROR | r/m, CL | 1101001w | mod001r/m | ROR | r/m, imm8 | 1100000w | mod001r/m | data | RCL | r/m, 1 | 1101000w | mod010r/m | RCL | r/m, CL | 1101001w | mod010r/m | RCL | r/m, imm8 | 1100000w | mod010r/m | data | RCR | r/m, 1 | 1101000w | mod011r/m | RCR | r/m, CL | 1101001w | mod011r/m | RCR | r/m, imm8 | 1100000w | mod011r/m | data | SHLD | r/m16/32, reg16/32, imm8 | 00001111 | 10100100 | modregr/m | data | SHLD | r/m16/32, reg16/32, imm8 | 00001111 | 10100101 | modregr/m | SHRD | r/m16/32, reg16/32, imm8 | 00001111 | 10101100 | modregr/m | data | SHRD | r/m16/32, reg16/32, imm8 | 00001111 | 10101101 | modregr/m |
---|
Команды битовых и байтовых операций
Мнемокод | Операнд | Код | BT | r/m16/32, reg16/32 | 00001111 | 10100011 | mоdregr/m | BT | r/m16/32, imm8 | 00001111 | 10111010 | mоd100r/m | data | BTS | r/m16/32, reg16/32 | 00001111 | 10111011 | mоdregr/m | BTS | r/m16/32, imm8 | 00001111 | 10111010 | mоd111r/m | data | BTR | r/m16/32, reg16/32 | 00001111 | 10110011 | mоdregr/m | BTR | r/m16/32, imm8 | 00001111 | 10111010 | mоd110r/m | data | BTC | r/m16/32, reg16/32 | 00001111 | 10101011 | mоdregr/m | BTC | r/m16/32, imm8 | 00001111 | 10111010 | mоd101r/m | data |
---|
Команды операций со строками символов
Мнемокод | Операнд | Код | LODSB | - | 10101100 | LODSW | - | 10101101 | LODSD | - | 10101101 | STOSB | - | 10101010 | STOSW | - | 10101011 | STOSD | - | 10101011 | MOVSB | - | 10100100 | MOVSW | - | 10100101 | MOVSD | - | 10100101 | INSB | - | 01101100 | INSW | - | 01101101 | INSD | - | 01101101 | OUTSB | - | 01101110 | OUTSW | - | 01101111 | OUTSD | - | 01101111 | SCASB | - | 10101110 | SCASW | - | 10101111 | SCASD | - | 10101111 | CMPSB | - | 10100110 | CMPSW | - | 10100111 | CMPSD | - | 10100111 | REP | - | 11110011 | REPE | - | 11110011 | REPZ | - | 11110011 | REPNE | - | 11110010 | REPNZ | - | 11110010 |
---|
2. Операции управления
Команды передачи управления и прерывания
Мнемокод | Операнд | Код | JMP NEAR | disp8/16/32 | 111010s1 | data | JMP NEAR | r/m16/32 | 11111111 | mod100r/m | JMP FAR | disp16:disp16/32 | 11101010 | data | JMP FAR | r/m16:16/32 | 11111111 | mod101r/m | CALL NEAR | disp8/16/32 | 11101000 | data | CALL NEAR | r/m16/32 | 11111111 | mod010r/m | CALL FAR | disp16:disp16/32 | 10011010 | data | CALL FAR | r/m16:16/32 | 11111111 | mod011r/m | RET NEAR | - | 11000011 | RET NEAR | disp16 | 11000010 | data | RET FAR | - | 11001011 | RET FAR | disp16 | 11001010 | data | RET FAR | disp16 | 11001010 | data | Jcc | disp8 | 0111cccc | data | Jcc | disp16/32 | 00001111 | 1000сссс | data | JCXE | disp8 | 11100011 | data | LOOP | disp8 | 11100010 | data | LOOPE | disp8 | 11100001 | data | LOOPZ | disp8 | 11100001 | data | LOOPE | disp8 | 11100000 | data | LOOPZ | disp8 | 11100000 | data | INT | imm8 | 11001101 | data | INT | 3 | 11001100 | INTO | - | 11001110 | IRET | - | 11001111 | IRETD | - | 11001111 |
---|
Команды управления флагами
Мнемокод | Операнд | Код | CLI | - | 11111010 | STI | - | 11111011 | CLC | - | 11111000 | STC | - | 11111001 | CMC | - | 11110101 | CLD | - | 11111100 | STD | - | 11111101 | LAHF | - | 10011111 | SAHF | - | 10011110 | PUSHF | - | 10011100 | PUSHFD | - | 10011100 | POPF | - | 10011101 | POPFD | - | 10011101 |
---|
Команды поддержки языков высокого уровня и управления защитой памяти
Мнемокод | Операнд | Код | BOUND | reg16/32 | 01100010 | mоdregr/m | ENTER | imm16, imm8 | 11001000 | data | data | LEAVE | - | 11001001 | LGDT | mem16 | 00001111 | 00000001 | mod010r/m | SGDT | mem16 | 00001111 | 00000001 | mod000r/m | LIDT | mem16 | 00001111 | 00000001 | mod110r/m | SIDT | mem16 | 00001111 | 00000001 | mod001r/m | LLDT | r/m16 | 00001111 | 00000000 | mod010r/m | SLDT | r/m16 | 00001111 | 00000000 | mod000r/m | LTR | r/m16 | 00001111 | 00000000 | mod011r/m | STR | r/m16 | 00001111 | 00000000 | mod001r/m | CLTS | - | 00001111 | 00000110 | LAR | reg16/reg32, r/m16/32 | 00001111 | 00000010 | mоdregr/m | LSL | reg16/reg32, r/m16/32 | 00001111 | 00000011 | mоdregr/m | ARPL | r/m16, reg16 | 01100011 | mоdregr/m | VERR | r/m16 | 00001111 | 00000000 | mod100r/m | VERW | r/m16 | 00001111 | 00000000 | mod101r/m |
---|
Команды управления процессором и префиксные байты
Мнемокод | Операнд | Код | LMSW | r/m16 | 00001111 | 00000001 | mod110r/m | SMSW | r/m16 | 00001111 | 00000001 | mod100r/m | NOP | - | 10010000 | HLT | - | 11111000 |
---|
3. Таблицы для удобной работы с операндами
Типы операндов
Код | Имя | Описание |
---|---|---|
0 | - | Нет операнда |
1 | r/m | Регистр-память (8-ми, 16-ти или 32-х разрядные) |
2 | reg | Регистр (8-ми, 16-ти или 32-х разрядный) |
3 | mem | Память |
4 | seg | Сегментный регистр |
5 | acc | Регистр аккумулятор |
6 | imm | Непосредственные данные |
7 | disp | Смещение |
8 | sys | Системный регистр |
Общий формат команд
Код | MODR/M | SIB | DISP | IMM |
---|---|---|---|---|
1 или 2 байта | 0 или 1 байт | 0 или 1 байт | 0, 1, 2 или 4 байта | 0, 1, 2 или 4 байта |
Биты, влияющие на код операции
Имя | Описание |
---|---|
d | d = 0 - reg/код - источник, r/m - приёмник, d = 1 - наоборот |
w | w = 0 - 8 бит, w = 1 - 16/32 бита |
s | s = 1 - imm8, s = 0 - imm16/32 |
g | g = 1 - отладочный системный регистр |
t | t = 1 - тестовый системный регистр |
Формат байта MODR/M
7 6 | 5 4 3 | 2 1 0 |
---|---|---|
mod | reg/код | r/m |
Формат байта SIB
7 6 | 5 4 3 | 2 1 0 |
---|---|---|
ss | index | base |
Кодировка регистров общего назначения (поля reg)
reg | w=0 (8 бит) | w=1 (16 бит) | w=1 (32 бит) |
---|---|---|---|
000 | AL | AX | EAX |
001 | CL | CX | ECX |
002 | DL | DX | EDX |
003 | BL | BX | EBX |
004 | AH | SP | ESP |
005 | CH | BP | EBP |
006 | DH | SI | ESI |
007 | CH | DI | EDI |
Назначение поля seg (3 бита)
seg | регистр |
---|---|
000 | ES |
001 | CS |
010 | SS |
011 | DS |
100 | FS |
101 | GS |
Кодировка поля sys - системные регистры CRi, DRi, TRi (3 бита)
sys | CRi | DRi | TRi |
---|---|---|---|
000 | CR0 | DR0 | - |
001 | - | DR1 | - |
010 | CR2 | DR2 | - |
011 | CR3 | DR3 | - |
100 | - | - | - |
101 | - | - | - |
110 | - | DR6 | TR6 |
111 | - | DR7 | TR6 |
Назначение поля r/m для 16-ти битного режима
r/m | mod=00 | mod=01 | mod=10 |
---|---|---|---|
000 | [BX+SI] | [BX+SI+disp8] | [BX+SI+disp16] |
001 | [BX+DI] | [BX+DI+disp8] | [BX+DI+disp16] |
010 | [BP+SI] | [BP+SI+disp8] | [BP+SI+disp16] |
011 | [BP+DI] | [BP+DI+disp8] | [BP+DI+disp16] |
100 | [SI] | [SI+disp8] | [SI+disp16] |
101 | [DI] | [DI+disp8] | [DI+disp16] |
110 | [disp16] | [BP+disp8] | [BP+disp16] |
111 | [BX] | [BX+disp8] | [BX+disp16] |
Назначение поля r/m для 32-х битного режима
r/m | mod=00 | mod=01 | mod=10 |
---|---|---|---|
000 | [EAX] | [EAX+disp8] | [EAX+disp16] |
001 | [ECX] | [ECX+disp8] | [ECX+disp16] |
010 | [EDX] | [EDX+disp8] | [EDX+disp16] |
011 | [EBX] | [EBX+disp8] | [EBX+disp16] |
100 | см. табл. ниже | см. табл. ниже | см. табл. ниже |
101 | [disp32] | [EBP+disp8] | [EBP+disp32] |
110 | [ESI] | [ESP+disp8] | [ESP+disp32] |
111 | [EDI] | [EDI+disp8] | [EDI+disp32] |
Назначение поля base, для r/m = 100 (32-х битный режим)
r/m | mod=00 | mod=01 | mod=10 |
---|---|---|---|
000 | [EAX+(IR*F)] | [EAX+(IR*F)+disp8] | [EAX+(IR*F)+disp32] |
001 | [ECX+(IR*F)] | [ECX+(IR*F)+disp8] | [ECX+(IR*F)+disp32] |
010 | [EDX+(IR*F)] | [EDX+(IR*F)+disp8] | [EDX+(IR*F)+disp32] |
011 | [EBX+(IR*F)] | [EBX+(IR*F)+disp8] | [EBX+(IR*F)+disp32] |
100 | [ESP+(IR*F)] | [ESP+(IR*F)+disp8] | [ESP+(IR*F)+disp32] |
101 | [disp32+(IR*F)] | [EBP+(IR*F)+disp8] | [EBP+(IR*F)+disp32] |
110 | [ESI+(IR*F)] | [ESI+(IR*F)+disp8] | [ESI+(IR*F)+disp32] |
111 | [EDI+(IR*F)] | [EDI+(IR*F)+disp8] | [EDI+(IR*F)+disp32] |
Кодировка масштабного множителя F
ss | F |
---|---|
00 | 1 |
01 | 2 |
10 | 4 |
11 | 8 |
Кодировка индексного регистра IR в байте SIB
index | IR |
---|---|
000 | EAX |
001 | ECX |
010 | EDX |
011 | EBX |
100 | - |
101 | EBP |
110 | ESI |
111 | EDI |
Разрядность операндов и относительных адресов в защищённом режиме
Значение бита d | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
Префикс OS (66H) | - | - | + | + | - | - | + | + |
Префикс AS (67H) | - | + | - | + | - | + | - | + |
Разрядность операнда | 16 | 16 | 32 | 32 | 32 | 32 | 16 | 16 |
Разрядность адреса | 16 | 32 | 16 | 32 | 32 | 16 | 32 | 16 |
Формирование команд условных переходов
cccc | Мнемоника Jcc |
---|---|
0000 | JO |
0001 | JNO |
0010 | JB, JNAE |
0011 | JNB, JAE |
0100 | JE, JZ |
0101 | JNE, JNZ |
0110 | JBE, JNA |
0111 | JNBE, JA |
1000 | JS |
1001 | JNS |
1010 | JP, JPE |
1011 | JNP, JPO |
1100 | JL, JNGE |
1101 | JNL, JGE |
1110 | JLE, JNG |
1111 | JNLE, JG |
Буду очень благодарен, если вы укажите ошибки, которые могли возникнуть при опубликовании этих таблиц.