commit 923305236bcc5057428793a83fad7fc77f2ca4f3 from: Onana Onana Xavier Manuel date: Mon Sep 28 01:16:29 2026 UTC Added cmp and inc commit - 221a1b719280333b07e0739eeef1308433a758fe commit + 923305236bcc5057428793a83fad7fc77f2ca4f3 blob - 98a6df92252d1ffb9d3d547479793d5adc94c6ca blob + a422333b0d09daf877bbbd0e4082f9954ede2c9f --- tools/6c +++ tools/6c @@ -4,7 +4,7 @@ -- TOKEN MATCHING ----------------------------------------------------------------------- local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", - "jmp", "dec", "jz", "jnz" } + "jmp", "dec", "jz", "jnz", "cmp", "inc" } -- This is kinda a double definition but fix later :^) local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" } @@ -56,6 +56,7 @@ end local MAX_S16 = 2^15-1 local MIN_S16 = -2^15 local MAX_U16 = 2^16 +local MAX_U32 = 2^32 ----------------------------------------------------------------------- -- DEBUGING @@ -217,7 +218,15 @@ local function writeu32(dst, value) dst:write(string.char(b1, b2, b3, b4)) -- Little Endian x86 end +local function writes32(dst, value) + if value < 0 then + value = MAX_U32 + value + end + writeu32(dst, value) +end + + local function intval(intstr) local len = #intstr local res = 0 @@ -400,6 +409,10 @@ ast.genast = function(expr) end ast.eval = function(node) + if tonumber(node) ~= nil then + return { tonumber(node) } + end + if node.data[1] == "number" then return { tonumber(node.data[2]) or 0 } end blob - 38f73f4bb1f280db4f59b2f47943154e35488a3d blob + ab515874c65a09776f2571749e6e6ee0f8379fe0 --- tools/6l +++ tools/6l @@ -4,7 +4,7 @@ -- TOKEN MATCHING ----------------------------------------------------------------------- local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", - "jmp", "dec", "jz", "jnz" } + "jmp", "dec", "jz", "jnz", "cmp", "inc" } -- This is kinda a double definition but fix later :^) local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" } @@ -56,6 +56,7 @@ end local MAX_S16 = 2^15-1 local MIN_S16 = -2^15 local MAX_U16 = 2^16 +local MAX_U32 = 2^32 ----------------------------------------------------------------------- -- DEBUGING @@ -217,7 +218,15 @@ local function writeu32(dst, value) dst:write(string.char(b1, b2, b3, b4)) -- Little Endian x86 end +local function writes32(dst, value) + if value < 0 then + value = MAX_U32 + value + end + writeu32(dst, value) +end + + local function intval(intstr) local len = #intstr local res = 0 @@ -400,6 +409,10 @@ ast.genast = function(expr) end ast.eval = function(node) + if tonumber(node) ~= nil then + return { tonumber(node) } + end + if node.data[1] == "number" then return { tonumber(node.data[2]) or 0 } end @@ -925,6 +938,21 @@ local function writejmp(inst, curr) end end +local function writecmp(inst, eval) + if inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then + local op = inst.operands[2] + local modrm = eval.modrm + local imm8 = (op.type == tk_type["hexadecimal"]) and hexval(op.raw) or intval(op.raw) + + modrm = band(eval.modrm, bitval("0b11000111")) + modrm = bor(modrm, bitval("0b00111000")) + + writeu8(dst, hexval("0h80")) + writeu8(dst, modrm) + writeu8(dst, imm8) + end +end + local function get_instruction_size(hdr, inst) if hdr.type == tk_type["mov"] then local opcount = #inst.details @@ -961,16 +989,27 @@ local function get_instruction_size(hdr, inst) if inst.details[1] == ASM_R8 then return 2 end + + elseif hdr.type == tk_type["inc"] then + if inst.details[1] == ASM_R8 then + return 2 + end + elseif hdr.type == tk_type["jz"] then if inst.details[1] == ASM_LABEL then return 4 -- WE ASSUME IT IS REAL MODE HENCE A 2 BYTES ADDRESS end + elseif hdr.type == tk_type["jnz"] then if inst.details[1] == ASM_LABEL then return 4 -- WE ASSUME ITS REAL MODE else perror("jnz only support labels for now") end + elseif hdr.type == tk_type["cmp"] then + if inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then + return 3 + end end return 0 end @@ -1093,6 +1132,13 @@ while true do writeu8(dst, eval.modrm) end + elseif hdr.type == tk_type["inc"] then + if inst.details[1] == ASM_R8 then + local modrm = band(eval.modrm, bitval("0b11000111")) + + writeu8(dst, hexval("0hFE")) + writeu8(dst, modrm) + end elseif hdr.type == tk_type["jz"] then if inst.details[1] == ASM_LABEL then local addr = symbol_table[inst.operands[1].raw] @@ -1121,6 +1167,8 @@ while true do writes16(dst, addr - coffset) end + elseif hdr.type == tk_type["cmp"] then + writecmp(inst, eval) end end end blob - 4d889701ee2fbcdd8d607ff6366016bcbe0da108 blob + bebf513b56d50f1ce90cb3994db35cbbfa782e46 --- tools/boot.sc +++ tools/boot.sc @@ -10,9 +10,20 @@ print: inter: call print dec bl - jz end jnz inter +} + +asm { + mov cl, 0 +second: + mov ah, 0h0e + mov al, 0h41 + int 0h10 + inc cl + cmp cl, 33 + jz end + jmp second end: - mov [ 0h100 + 300], bl + mov [ 0h30 ], bl hlt } blob - 4b79652e60434d0c33b5a3c10731898ff2e848f0 blob + fde3083bfbc7d30f4de8c831e63a279544968e3c --- tools/linker.lua +++ tools/linker.lua @@ -461,6 +461,21 @@ local function writejmp(inst, curr) end end +local function writecmp(inst, eval) + if inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then + local op = inst.operands[2] + local modrm = eval.modrm + local imm8 = (op.type == tk_type["hexadecimal"]) and hexval(op.raw) or intval(op.raw) + + modrm = band(eval.modrm, bitval("0b11000111")) + modrm = bor(modrm, bitval("0b00111000")) + + writeu8(dst, hexval("0h80")) + writeu8(dst, modrm) + writeu8(dst, imm8) + end +end + local function get_instruction_size(hdr, inst) if hdr.type == tk_type["mov"] then local opcount = #inst.details @@ -497,16 +512,27 @@ local function get_instruction_size(hdr, inst) if inst.details[1] == ASM_R8 then return 2 end + + elseif hdr.type == tk_type["inc"] then + if inst.details[1] == ASM_R8 then + return 2 + end + elseif hdr.type == tk_type["jz"] then if inst.details[1] == ASM_LABEL then return 4 -- WE ASSUME IT IS REAL MODE HENCE A 2 BYTES ADDRESS end + elseif hdr.type == tk_type["jnz"] then if inst.details[1] == ASM_LABEL then return 4 -- WE ASSUME ITS REAL MODE else perror("jnz only support labels for now") end + elseif hdr.type == tk_type["cmp"] then + if inst.details[1] == ASM_R8 and inst.details[2] == ASM_IMM8 then + return 3 + end end return 0 end @@ -629,6 +655,13 @@ while true do writeu8(dst, eval.modrm) end + elseif hdr.type == tk_type["inc"] then + if inst.details[1] == ASM_R8 then + local modrm = band(eval.modrm, bitval("0b11000111")) + + writeu8(dst, hexval("0hFE")) + writeu8(dst, modrm) + end elseif hdr.type == tk_type["jz"] then if inst.details[1] == ASM_LABEL then local addr = symbol_table[inst.operands[1].raw] @@ -657,6 +690,8 @@ while true do writes16(dst, addr - coffset) end + elseif hdr.type == tk_type["cmp"] then + writecmp(inst, eval) end end end blob - 2ee3f42b8994baab795f1a6eb8b6c764f0f9b890 blob + f99efa741ad5ace5d4e48cf07471a770ffdfe6cf --- tools/util.lua +++ tools/util.lua @@ -2,7 +2,7 @@ -- TOKEN MATCHING ----------------------------------------------------------------------- local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", - "jmp", "dec", "jz", "jnz" } + "jmp", "dec", "jz", "jnz", "cmp", "inc" } -- This is kinda a double definition but fix later :^) local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" } @@ -54,6 +54,7 @@ end local MAX_S16 = 2^15-1 local MIN_S16 = -2^15 local MAX_U16 = 2^16 +local MAX_U32 = 2^32 ----------------------------------------------------------------------- -- DEBUGING @@ -215,7 +216,15 @@ local function writeu32(dst, value) dst:write(string.char(b1, b2, b3, b4)) -- Little Endian x86 end +local function writes32(dst, value) + if value < 0 then + value = MAX_U32 + value + end + writeu32(dst, value) +end + + local function intval(intstr) local len = #intstr local res = 0 @@ -398,6 +407,10 @@ ast.genast = function(expr) end ast.eval = function(node) + if tonumber(node) ~= nil then + return { tonumber(node) } + end + if node.data[1] == "number" then return { tonumber(node.data[2]) or 0 } end