commit 221a1b719280333b07e0739eeef1308433a758fe from: Onana Onana Xavier Manuel date: Sun Sep 27 23:31:43 2026 UTC Added jmp, jnz, jz and dec commit - d606d8179b1a8bf8fef0cadea6422d32dcba6e74 commit + 221a1b719280333b07e0739eeef1308433a758fe blob - b6a9421f8eeb2eb8f2dfe3c277f80eb68fd460fa blob + 98a6df92252d1ffb9d3d547479793d5adc94c6ca --- tools/6c +++ tools/6c @@ -4,7 +4,7 @@ -- TOKEN MATCHING ----------------------------------------------------------------------- local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", - "jmp" } + "jmp", "dec", "jz", "jnz" } -- This is kinda a double definition but fix later :^) local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" } blob - c9d1a7e6c036459bc69a9f9e4f5e04ff0279acdc blob + 38f73f4bb1f280db4f59b2f47943154e35488a3d --- tools/6l +++ tools/6l @@ -4,7 +4,7 @@ -- TOKEN MATCHING ----------------------------------------------------------------------- local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", - "jmp" } + "jmp", "dec", "jz", "jnz" } -- This is kinda a double definition but fix later :^) local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" } @@ -766,6 +766,13 @@ local function instvaluate(inst) return ret elseif opcount == 1 then -- amslyze caps it at 2 + if inst.details[1] == ASM_R8 then + local mod = "11" + local reg = "000" + local rm = regmap[gettokenkey(inst.operands[1])] + + ret.modrm = bitval("0b" .. mod .. reg .. rm) + end return ret else if inst.details[1] == ASM_R8 and inst.details[2] == ASM_R8 then @@ -902,6 +909,22 @@ local function writecall(inst, curr) end end +local function writejmp(inst, curr) + local opcount = #inst.details + + if opcount ~= 1 then + perror("jmp takes 1 operand " .. inst.operands[1].line) + end + + -- AGAIN THIS IS ASSUMED TO BE REAL MODE + if inst.details[1] == ASM_LABEL then + local addr = symbol_table[inst.operands[1].raw] + + writeu8(dst, hexval("0hE9")) + writes16(dst, addr - curr) + end +end + local function get_instruction_size(hdr, inst) if hdr.type == tk_type["mov"] then local opcount = #inst.details @@ -934,6 +957,20 @@ local function get_instruction_size(hdr, inst) return 2 elseif hdr.type == tk_type["call"] or hdr.type == tk_type["jmp"] then return 3 -- WE ASSUME ITS REAL MODE!!! + elseif hdr.type == tk_type["dec"] 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 end return 0 end @@ -1043,6 +1080,47 @@ while true do end elseif hdr.type == tk_type["call"] then writecall(inst, coffset) + + elseif hdr.type == tk_type["jmp"] then + writejmp(inst, coffset) + + elseif hdr.type == tk_type["dec"] then + if inst.details[1] == ASM_R8 then + eval.modrm = band(eval.modrm, bitval("0b11000111")) + eval.modrm = bor(eval.modrm, bitval("0b00001000")) + + writeu8(dst, hexval("0hFE")) + writeu8(dst, eval.modrm) + end + + elseif hdr.type == tk_type["jz"] then + if inst.details[1] == ASM_LABEL then + local addr = symbol_table[inst.operands[1].raw] + if addr == nil then + perror("attempt to jz to unknown label " .. inst.operands[1].raw .. " line " .. hdr.line) + end + + -- WE ASSUME THIS IS REAL MODE + writeu8(dst, hexval("0h0F")) + writeu8(dst, hexval("0h84")) + writes16(dst, addr - coffset) + else + perror("Unssuported jz target at line " .. hdr.line) + end + + elseif hdr.type == tk_type["jnz"] then + if inst.details[1] == ASM_LABEL then + local addr = symbol_table[inst.operands[1].raw] + if addr == nil then + perror("attempt to jnz to unknown label " .. inst.operands[1].raw .. " line " .. hdr.line) + end + + -- WE ASSUME ITS REAL MODE + writeu8(dst, hexval("0h0F")) + writeu8(dst, hexval("0h85")) + writes16(dst, addr - coffset) + end + end end end blob - 61f5a27365fe483db3abdbe669340a81ceff5a26 blob + 4d889701ee2fbcdd8d607ff6366016bcbe0da108 --- tools/boot.sc +++ tools/boot.sc @@ -1,16 +1,18 @@ asm { _start: + mov bl, 0hff + jmp inter +print: mov ah, 0h0e mov al, 0h61 int 0h10 - call me + ret +inter: + call print + dec bl + jz end + jnz inter +end: mov [ 0h100 + 300], bl hlt - -me: - mov ah, 0h0e - mov al, 0h61 - int 0h10 - call me - ret } blob - 2d754aaa964d81a62e0d9e71a668132a4d7c59fe blob + 4b79652e60434d0c33b5a3c10731898ff2e848f0 --- tools/linker.lua +++ tools/linker.lua @@ -302,6 +302,13 @@ local function instvaluate(inst) return ret elseif opcount == 1 then -- amslyze caps it at 2 + if inst.details[1] == ASM_R8 then + local mod = "11" + local reg = "000" + local rm = regmap[gettokenkey(inst.operands[1])] + + ret.modrm = bitval("0b" .. mod .. reg .. rm) + end return ret else if inst.details[1] == ASM_R8 and inst.details[2] == ASM_R8 then @@ -438,6 +445,22 @@ local function writecall(inst, curr) end end +local function writejmp(inst, curr) + local opcount = #inst.details + + if opcount ~= 1 then + perror("jmp takes 1 operand " .. inst.operands[1].line) + end + + -- AGAIN THIS IS ASSUMED TO BE REAL MODE + if inst.details[1] == ASM_LABEL then + local addr = symbol_table[inst.operands[1].raw] + + writeu8(dst, hexval("0hE9")) + writes16(dst, addr - curr) + end +end + local function get_instruction_size(hdr, inst) if hdr.type == tk_type["mov"] then local opcount = #inst.details @@ -470,6 +493,20 @@ local function get_instruction_size(hdr, inst) return 2 elseif hdr.type == tk_type["call"] or hdr.type == tk_type["jmp"] then return 3 -- WE ASSUME ITS REAL MODE!!! + elseif hdr.type == tk_type["dec"] 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 end return 0 end @@ -579,6 +616,47 @@ while true do end elseif hdr.type == tk_type["call"] then writecall(inst, coffset) + + elseif hdr.type == tk_type["jmp"] then + writejmp(inst, coffset) + + elseif hdr.type == tk_type["dec"] then + if inst.details[1] == ASM_R8 then + eval.modrm = band(eval.modrm, bitval("0b11000111")) + eval.modrm = bor(eval.modrm, bitval("0b00001000")) + + writeu8(dst, hexval("0hFE")) + writeu8(dst, eval.modrm) + end + + elseif hdr.type == tk_type["jz"] then + if inst.details[1] == ASM_LABEL then + local addr = symbol_table[inst.operands[1].raw] + if addr == nil then + perror("attempt to jz to unknown label " .. inst.operands[1].raw .. " line " .. hdr.line) + end + + -- WE ASSUME THIS IS REAL MODE + writeu8(dst, hexval("0h0F")) + writeu8(dst, hexval("0h84")) + writes16(dst, addr - coffset) + else + perror("Unssuported jz target at line " .. hdr.line) + end + + elseif hdr.type == tk_type["jnz"] then + if inst.details[1] == ASM_LABEL then + local addr = symbol_table[inst.operands[1].raw] + if addr == nil then + perror("attempt to jnz to unknown label " .. inst.operands[1].raw .. " line " .. hdr.line) + end + + -- WE ASSUME ITS REAL MODE + writeu8(dst, hexval("0h0F")) + writeu8(dst, hexval("0h85")) + writes16(dst, addr - coffset) + end + end end end blob - 73f2e4afc8a778a98f22a8aa3b4715360afdcf66 blob + 2ee3f42b8994baab795f1a6eb8b6c764f0f9b890 --- tools/util.lua +++ tools/util.lua @@ -2,7 +2,7 @@ -- TOKEN MATCHING ----------------------------------------------------------------------- local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", - "jmp" } + "jmp", "dec", "jz", "jnz" } -- This is kinda a double definition but fix later :^) local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" }