public override void Process(Assembler asm, ref string[] tokens) { // Get data int i = 1; string first = tokens[i++]; string value = tokens[i++]; // Check if value is number int num; bool valueIsNum = Util.ConvertStringToInt(value, out num); // Check if(Util.IsRegister32(first)) { Register reg = Util.GetRegister32(first); // MOV SOURCE, VALUE if (valueIsNum) { asm.Write8((byte)(0xB8 + (int)reg)); asm.Write32(num); } // MOV SOURCE, REG else if (Util.IsRegister32(value)) { Register src = Util.GetRegister32(value); asm.Write8(0x89); asm.Write8(Util.EncodeMODRM(3, (int)src, (int)reg)); } else { throw new Exception("Invalid source for MOV instruction '" + value + "'"); } } else if (Util.IsRegister16(first)) { Register reg = Util.GetRegister16(first); // MOV SOURCE, VALUE if (valueIsNum) { asm.Write8(0x66); asm.Write8((byte)(0xB8 + (int)reg)); asm.Write16((short) num); } // MOV SOURCE, REG else if (Util.IsRegister16(value)) { Register src = Util.GetRegister16(value); asm.Write8(0x66); asm.Write8(0x89); asm.Write8(Util.EncodeMODRM(3, (int)src, (int)reg)); } else { throw new Exception("Invalid source for MOV instruction '" + value + "'"); } } else if (Util.IsRegister8(first)) { Register reg = Util.GetRegister8(first); // MOV SOURCE, VALUE if (valueIsNum) { asm.Write8((byte)(0xB0 + (int)reg)); asm.Write8((byte)num); } // MOV SOURCE, REG else if (Util.IsRegister8(value)) { Register src = Util.GetRegister8(value); asm.Write8(0x88); asm.Write8(Util.EncodeMODRM(3, (int)src, (int)reg)); } else { throw new Exception("Invalid source for MOV instruction '" + value + "'"); } } else { throw new Exception("Invalid MOV operation on '" + first + "'"); } }
public override void Process(Assembler asm, ref string[] tokens) { asm.Write8(0xF4); }
public override void Process(Assembler asm, ref string[] tokens) { // Get data int i = 1; string port = tokens[i++]; string value = tokens[i++]; // Check if port is number int portnum; bool valueIsNum = Util.ConvertStringToInt(port, out portnum); // Value is stored in either AL, AX or EAX if(Util.GetRegister8(value) != Register.AL && Util.GetRegister16(value) != Register.AX && Util.GetRegister32(value) != Register.EAX) { throw new Exception("The output value needs to be in either AL, AX or EAX, not '" + value + "'"); } // Check if (Util.IsRegister16(port)) { // OUTB expects DX as port if (Util.GetRegister16(port) == Register.DX) { if(Util.IsRegister8(value)) { asm.Write8(0xEE); } else if(Util.IsRegister16(value)) { asm.Write8(0x66); asm.Write8(0xEF); } else { asm.Write8(0xEF); } } else { throw new Exception("Invalid port for OUTB instruction '" + port + "'"); } } else if(valueIsNum) { // Check if port number is in valid range if(portnum >= 0 && portnum <= 65535) { if (Util.IsRegister8(value)) { asm.Write8(0xE6); asm.Write8((byte)portnum); } else if (Util.IsRegister16(value)) { asm.Write8(0x66); asm.Write8(0xE7); asm.Write8((byte)portnum); } else { asm.Write8(0xE7); asm.Write8((byte)portnum); } } else { throw new Exception("Invalid port number, must be in range [0, 65536] not '" + port + "'"); } } else { throw new Exception("Invalid port for OUTB instruction '" + port + "'"); } }