#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{{Register32("eax"), 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{{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{{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{{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 args{{Immediate8(5)}}; segment.push_back(makeOp("int", args)); segment.push_back(makeOp("ret")); segment.push_back(makeLabel("data1")); segment.push_back(makeData({1, 2, 3})); ASSERT_EQ(segment.size(), 5); ASSERT_EQ(segment.getCode(), std::vector({0x90, 0xCD, 0x05, 0xC3, 0x01, 0x02, 0x03})); }