commit d606d8179b1a8bf8fef0cadea6422d32dcba6e74 from: Onana Onana Xavier Manuel date: Sun Sep 27 22:17:43 2026 UTC Fixed call rel16 bug in linker.lua commit - 26477129cfe7ccef1bfb485f8ee107b557c9f9fa commit + d606d8179b1a8bf8fef0cadea6422d32dcba6e74 blob - 382df3706cb70a0adeab9a245c2fadc3bfe38831 blob + b6a9421f8eeb2eb8f2dfe3c277f80eb68fd460fa --- tools/6c +++ tools/6c @@ -3,7 +3,8 @@ ----------------------------------------------------------------------- -- TOKEN MATCHING ----------------------------------------------------------------------- -local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call" } +local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", + "jmp" } -- This is kinda a double definition but fix later :^) local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" } @@ -52,8 +53,9 @@ end ----------------------------------------------------------------------- -- CONSTANTS ----------------------------------------------------------------------- -local MAX_S16 = 2^16-1 -local MIN_S16 = -2^16 +local MAX_S16 = 2^15-1 +local MIN_S16 = -2^15 +local MAX_U16 = 2^16 ----------------------------------------------------------------------- -- DEBUGING @@ -198,6 +200,14 @@ local function writeu16(dst, value) dst:write(string.char(b1, b2)) -- Little Endian x86 end +local function writes16(dst, value) + if value < 0 then + value = MAX_U16 + value + end + + writeu16(dst, value) +end + local function writeu32(dst, value) local b4 = band(brshift(value, 24), 0xff) local b3 = band(brshift(value, 16), 0xff) blob - 04a04989c870c5a0d8575f4f57bcc28f19e0bf48 blob + c9d1a7e6c036459bc69a9f9e4f5e04ff0279acdc --- tools/6l +++ tools/6l @@ -3,7 +3,8 @@ ----------------------------------------------------------------------- -- TOKEN MATCHING ----------------------------------------------------------------------- -local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call" } +local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", + "jmp" } -- This is kinda a double definition but fix later :^) local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" } @@ -52,8 +53,9 @@ end ----------------------------------------------------------------------- -- CONSTANTS ----------------------------------------------------------------------- -local MAX_S16 = 2^16-1 -local MIN_S16 = -2^16 +local MAX_S16 = 2^15-1 +local MIN_S16 = -2^15 +local MAX_U16 = 2^16 ----------------------------------------------------------------------- -- DEBUGING @@ -198,6 +200,14 @@ local function writeu16(dst, value) dst:write(string.char(b1, b2)) -- Little Endian x86 end +local function writes16(dst, value) + if value < 0 then + value = MAX_U16 + value + end + + writeu16(dst, value) +end + local function writeu32(dst, value) local b4 = band(brshift(value, 24), 0xff) local b3 = band(brshift(value, 16), 0xff) @@ -560,7 +570,6 @@ local function operlyze(op, ret) if val < 256 then table.insert(ret.details, ASM_IMM8) - table.insert(ret.operands, op) else perror("operand 1 of instruction on line " .. op.line .. " is too big!") end @@ -888,31 +897,37 @@ local function writecall(inst, curr) if inst.details[1] == ASM_LABEL then local addr = symbol_table[inst.operands[1].raw] writeu8(dst, hexval("0hE8")) - writeu16(dst, addr - curr) + + writes16(dst, addr - curr) end end local function get_instruction_size(hdr, inst) if hdr.type == tk_type["mov"] then - local size = 2 - local eval = instvaluate(inst) - if eval.modrm ~= nil then size = size + 1 end - - -- Check expression for memory constants - if inst.memblock and inst.memblock.expression then - for _, v in ipairs(inst.memblock.expression) do - local num = tonumber(v) - if num ~= nil then - if num <= MAX_S16 and num >= MIN_S16 then - size = size + 2 - else - size = size + 4 - end - end - end - end - return size + 1 -- Plus your trailing byte modifier + local opcount = #inst.details + if opcount ~= 2 then perror("mov requires 2 operands") end + + if (inst.details[1] == ASM_R8 or inst.details[1] == ASM_IMM8) and (inst.details[2] == ASM_R8 or inst.details[2] == ASM_IMM8) then + return 3 + elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then + local size = 2 + if inst.memblock and inst.memblock.expression then + for _, v in ipairs(inst.memblock.expression) do + local num = tonumber(v) + if num ~= nil then + if num <= MAX_S16 and num >= MIN_S16 then + size = size + 2 + else + size = size + 4 + end + end + end + end + + return size + end + elseif hdr.type == tk_type["hlt"] or hdr.type == tk_type["ret"] or hdr.type == tk_type["cli"] then return 1 elseif hdr.type == tk_type["int"] then @@ -963,6 +978,8 @@ while true do end end +print(offset) + ----------------------------------------------------------------------- -- 2nd pass binary generation ----------------------------------------------------------------------- blob - b5e6dcbb21ab9e6ad6c2c3d81931e9250b2dd73d blob + 61f5a27365fe483db3abdbe669340a81ceff5a26 --- tools/boot.sc +++ tools/boot.sc @@ -11,5 +11,6 @@ me: mov ah, 0h0e mov al, 0h61 int 0h10 + call me ret } blob - 0fdab57d6e3d4e1ff757a04a8e37754252a4ff66 blob + 2d754aaa964d81a62e0d9e71a668132a4d7c59fe --- tools/linker.lua +++ tools/linker.lua @@ -106,7 +106,6 @@ local function operlyze(op, ret) if val < 256 then table.insert(ret.details, ASM_IMM8) - table.insert(ret.operands, op) else perror("operand 1 of instruction on line " .. op.line .. " is too big!") end @@ -434,31 +433,37 @@ local function writecall(inst, curr) if inst.details[1] == ASM_LABEL then local addr = symbol_table[inst.operands[1].raw] writeu8(dst, hexval("0hE8")) - writeu16(dst, addr - curr) + + writes16(dst, addr - curr) end end local function get_instruction_size(hdr, inst) if hdr.type == tk_type["mov"] then - local size = 2 - local eval = instvaluate(inst) - if eval.modrm ~= nil then size = size + 1 end - - -- Check expression for memory constants - if inst.memblock and inst.memblock.expression then - for _, v in ipairs(inst.memblock.expression) do - local num = tonumber(v) - if num ~= nil then - if num <= MAX_S16 and num >= MIN_S16 then - size = size + 2 - else - size = size + 4 - end - end - end - end - return size + 1 -- Plus your trailing byte modifier + local opcount = #inst.details + if opcount ~= 2 then perror("mov requires 2 operands") end + + if (inst.details[1] == ASM_R8 or inst.details[1] == ASM_IMM8) and (inst.details[2] == ASM_R8 or inst.details[2] == ASM_IMM8) then + return 3 + elseif inst.details[1] == ASM_MEM8 and inst.details[2] == ASM_R8 then + local size = 2 + if inst.memblock and inst.memblock.expression then + for _, v in ipairs(inst.memblock.expression) do + local num = tonumber(v) + if num ~= nil then + if num <= MAX_S16 and num >= MIN_S16 then + size = size + 2 + else + size = size + 4 + end + end + end + end + + return size + end + elseif hdr.type == tk_type["hlt"] or hdr.type == tk_type["ret"] or hdr.type == tk_type["cli"] then return 1 elseif hdr.type == tk_type["int"] then @@ -509,6 +514,8 @@ while true do end end +print(offset) + ----------------------------------------------------------------------- -- 2nd pass binary generation ----------------------------------------------------------------------- blob - 8c0a97bff15a71cc55d2ef7d551a6fd5d1aa633a blob + 73f2e4afc8a778a98f22a8aa3b4715360afdcf66 --- tools/util.lua +++ tools/util.lua @@ -1,7 +1,8 @@ ----------------------------------------------------------------------- -- TOKEN MATCHING ----------------------------------------------------------------------- -local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call" } +local mnemonics = { "mov", "cli", "hlt", "ret", "sti", "int", "call", + "jmp" } -- This is kinda a double definition but fix later :^) local arithmetics = { "+", "-", "*", "/", "^", "~", "|", "&" } @@ -50,8 +51,9 @@ end ----------------------------------------------------------------------- -- CONSTANTS ----------------------------------------------------------------------- -local MAX_S16 = 2^16-1 -local MIN_S16 = -2^16 +local MAX_S16 = 2^15-1 +local MIN_S16 = -2^15 +local MAX_U16 = 2^16 ----------------------------------------------------------------------- -- DEBUGING @@ -196,6 +198,14 @@ local function writeu16(dst, value) dst:write(string.char(b1, b2)) -- Little Endian x86 end +local function writes16(dst, value) + if value < 0 then + value = MAX_U16 + value + end + + writeu16(dst, value) +end + local function writeu32(dst, value) local b4 = band(brshift(value, 24), 0xff) local b3 = band(brshift(value, 16), 0xff)