MACHINE INSTRUCTIONS Part B Here is a list of instructions that have a mod byte including those described in Part A. The 6-bit opcodes involved are: add 000000 adc 000100 sub 001010 sbb 000110 cmp 001110 and 001000 or 000010 xor 001100 mov 100010 lea 100011 In each of the above cases, the 6-bit opcode is followed by 2 bits called the d (direction) bit and the w (width) bit. For instance, the 1st byte of the sub instruction is represented as: 001010dw As described before If w = 0, the instruction is a BYTE operation If w = 1, the instruction is a WORD operation The function of the d bit can be illustrated by considering the examples given in the Introduction: direction width opcode mod reg r/m 00101010 11011010 was given as the instruction: sub bl, dl The opcode byte in this case is 001010dw where d = 1 and w = 0. If d were set as 0 as in: 00101000 11011010 then the instruction would be: sub dl, bl 00011011 00011001 00110110 2A01 was given as the instruction: sbb si, num 00110110 2A01 is then the instruction: sbb num, si As you can see from these examples if the d-bit is 1, then the register specified in bits 4-6 of the mod byte is the destination. If the d-bit is 0, then this register is the source. THE MOD BYTE The reg field specifies the register which forms one of the operands. As mentioned above, this register serves as the destination if the d-bit is 1. The mod and r/m fields within the mod byte together define the characteristic of the other operand. This operand can be: (a) a register in which case the mod field is 11, and the r/m field specifies the register involved using the code defined in the Introduction to Machine instructions. (b) a direct operand, in which case the mod field is 00 and r/ m is 110. The offset of the direct operand follows, first the low-order byte, and then the high-order byte. An example of this was given in the Introduction. (c) an indirect operand, such as e.g mov ax, [si + bx + 12FF]. In this case 12FF is an 8-bit displacement and si + bx is the register combination involved. The mod field specifies the size of the displacement, as follows: mod field size of displacement 00 0 except that the combination mod = 00 and r/m = 110 is employed for case (b). 01 8-bit 10 16-bit (Recall that mod = 11 is employed for case (a)) The r/m field here specifies the combination of registers involved as follows; r/m field register combination 000 bx + si 001 bx + di 010 bp + si 011 bp + di 100 si 101 di 110 bp 111 bx IMMEDIATE OPERANDS With the mode byte and the d-bit, we can code any instruction in which one of the operands is a register, and the other is a register, a direct operand, or an indirect operand. The only combination of operands that this does not cover are ones which involve an immediate operand. Special opcodes are assigned for such instructions. The format of most of these instructions is as follows: 7 op-code bits w-bit mod field (2 bits) 3 additional op-code bits r/m field (3 bits) Note that there is no d-bit. The immediate operand is always the source. For example the subtract immediate instruction may be coded as follows: 1000000w mod 101 r/m displacement bytes,if any immediate operand The immediate operand, in this case, is a byte if w=0 and it's a word if w=1. The displacement byte for indirect operands has been described above. The mod and r/m specify the non-immediate destination operand, which can be a register, direct operand, or indirect operand as described in the description of the mod byte above. Here are some examples of the op-code bits involved for different immediate instructions: Instruction 7 opcode bits 3 addt'n op-code bits in opcode byte in mod byte add 1000000 000 adc 1000000 010 sub 1000000 101 sbb 1000000 010 cmp 1000000 111 and 1000000 100 or 1000000 001 xor 1000000 110 mov 1100011 000 GENERATING CODE The data structure required for instructions with a mod byte is of the form:: char code_stack[3000]; /* where the code generated is stored */ int code_stacki = 1; /* The next free position in code_stack */ typedef struct { unsigned w:1, d:1, opcode:6, r_m:3, reg:3, mod:2, low_byte:8, high_byte:8; } instruction; instruction * ip; Example: generating code for sub bl, dl ip = (instruction *) (code_stack + code_stacki); ip -> opcode = 0x0A; /* 001010 */ ip -> d = 1; ip -> w = 0; ip -> mod = 3; ip -> reg = 3; /* bl */ ip -> r_m = 2; /* dl */ codestacki += 2; CODES EMPLOYED IN INSTRUCTIONS d: 0=from w: 0=byte 1=to 1=word mod: 00 disp=0 (i.e. no displacement) - except if r/m=110 then operand is direct with offset = disphigh:disp-low 01 disp=disp-low (i.e. 8 bits) 10 disp=disp-high, disp-low (i.e. 16 bits) 11 r/m is the reg field as defined below r/m denotes indirect operand, where disp is as defined by mm above: 000 BX+SI+disp 001 BX+DI+disp 010 BP+SI+disp 011 BP+DI+disp 100 SI+disp 101 DI+disp 110 BP+disp - except if mod = 0 then operand is direct with offset = disphigh:disp-low 111 BX+disp w reg: 0 000 AL 0 001 CL 0 010 DL 0 011 BL 0 100 AH 0 101 CH 0 110 DH 0 111 BH 1 000 AX 1 001 CX 1 010 DX 1 011 BX 1 100 SP 1 101 BP 1 110 SI 1 111 DI segment register: 00 ES 01 CS 10 SS 11 DS