#include "asm/chunk.h" #include "asm/assembler.h" #include "asm/segment.h" #include "asm/intel64/all_ops.h" #include "minicc.h" #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include #include #include #include #include #include #include #include #include using namespace std::string_literals; namespace fs = std::filesystem; class AsmTest: public ::testing::Test { protected: AsmTest() { //debug = true; } ~AsmTest() { } void SetUp(){ } void TearDown(){ } }; TEST_F(AsmTest, Intel64_add) { Segment segment; AsmArgs args{{AsmArgs::Register32("eax"), AsmArgs::Immediate32(1)}}; segment.push_back(makeOp("add", args)); ASSERT_EQ(segment.size(), 1); ASSERT_EQ(segment.getCode(), std::vector({0x05, 0x01, 0x00, 0x00, 0x00})); } TEST_F(AsmTest, Intel64_int_0) { Segment segment; AsmArgs args{{AsmArgs::Immediate8(0)}}; segment.push_back(makeOp("int", args)); ASSERT_EQ(segment.size(), 1); ASSERT_EQ(segment.getCode(), std::vector{0xCE}); } TEST_F(AsmTest, Intel64_int_1) { Segment segment; AsmArgs args{{AsmArgs::Immediate8(1)}}; segment.push_back(makeOp("int", args)); ASSERT_EQ(segment.size(), 1); ASSERT_EQ(segment.getCode(), std::vector{0xF1}); } TEST_F(AsmTest, Intel64_int_5) { Segment segment; AsmArgs args{{AsmArgs::Immediate8(5)}}; segment.push_back(makeOp("int", args)); ASSERT_EQ(segment.size(), 1); ASSERT_EQ(segment.getCode(), std::vector({0xCD, 0x05})); } TEST_F(AsmTest, Intel64_nop) { Segment segment; segment.push_back(makeOp("nop")); ASSERT_EQ(segment.size(), 1); ASSERT_EQ(segment.getCode(), std::vector{0x90}); } TEST_F(AsmTest, Intel64_ret) { Segment segment; segment.push_back(makeOp("ret")); ASSERT_EQ(segment.size(), 1); ASSERT_EQ(segment.getCode(), std::vector{0xC3}); } TEST_F(AsmTest, Intel64_multiple) { Segment segment; segment.push_back(makeOp("nop")); AsmArgs args0{{AsmArgs::Immediate8(5)}}; segment.push_back(makeOp("int", args0)); segment.push_back(makeOp("ret")); segment.push_back(makeLabel("data1")); segment.push_back(makeOp("ret")); AsmArgs args1{{AsmArgs::Label("data1")}}; segment.push_back(makeOp("jmp", args1)); segment.push_back(makeData({1, 2, 3})); segment.insertAddresses(); ASSERT_EQ(segment.size(), 7); ASSERT_EQ(segment.getCode(), std::vector( { 0x90, // nop 0xCD, 0x05, // int 5 0xC3, // ret // data1: 0xC3, // ret 0xE9, 0xFF, 0xFF, 0xFF, 0xFF, // jmp data1 0x01, 0x02, 0x03 // data })); segment.optimize(); ASSERT_EQ(segment.size(), 7); ASSERT_EQ(segment.getCode(), std::vector( { 0x90, // nop 0xCD, 0x05, // int 5 0xC3, // ret // data1: 0xC3, // ret 0xEB, 0xFF, // jmp data1 0x01, 0x02, 0x03 // data })); }