feat: debugage X86 sans bogues affichage avec GDB
This commit is contained in:
parent
72bf3f35c2
commit
26b8139657
|
@ -0,0 +1,468 @@
|
|||
# Special mode for GDB that allows to debug/disassemble REAL MODE x86 code
|
||||
#
|
||||
# It has been designed to be used with QEMU or BOCHS gdb-stub
|
||||
#
|
||||
# 08/2011 Hugo Mercier - GPL v3 license
|
||||
#
|
||||
# Freely inspired from "A user-friendly gdb configuration file" widely available
|
||||
# on the Internet
|
||||
|
||||
set confirm off
|
||||
set verbose off
|
||||
set prompt \033[31mreal-mode-gdb$ \033[0m
|
||||
|
||||
set output-radix 0d10
|
||||
set input-radix 0d10
|
||||
|
||||
# These make gdb never pause in its output
|
||||
set height 0
|
||||
set width 0
|
||||
|
||||
# Intel syntax
|
||||
set disassembly-flavor intel
|
||||
# Real mode
|
||||
set architecture i8086
|
||||
|
||||
set $SHOW_CONTEXT = 1
|
||||
|
||||
set $REAL_MODE = 1
|
||||
|
||||
# By default A20 is present
|
||||
set $ADDRESS_MASK = 0x1FFFFF
|
||||
|
||||
# nb of instructions to display
|
||||
set $CODE_SIZE = 20
|
||||
|
||||
define enable-a20
|
||||
set $ADDRESS_MASK = 0x1FFFFF
|
||||
end
|
||||
define disable-a20
|
||||
set $ADDRESS_MASK = 0x0FFFFF
|
||||
end
|
||||
|
||||
# convert segment:offset address to physical address
|
||||
define r2p
|
||||
if $argc < 2
|
||||
printf "Arguments: segment offset\n"
|
||||
else
|
||||
set $ADDR = (((unsigned long)$arg0 & 0xFFFF) << 4) + (((unsigned long)$arg1 & 0xFFFF) & $ADDRESS_MASK)
|
||||
printf "0x%05X\n", $ADDR
|
||||
end
|
||||
end
|
||||
document r2p
|
||||
Convert segment:offset address to physical address
|
||||
Set the global variable $ADDR to the computed one
|
||||
end
|
||||
|
||||
# get address of Interruption
|
||||
define int_addr
|
||||
if $argc < 1
|
||||
printf "Argument: interruption_number\n"
|
||||
else
|
||||
set $offset = (unsigned short)*($arg0 * 4)
|
||||
set $segment = (unsigned short)*($arg0 * 4 + 2)
|
||||
r2p $segment $offset
|
||||
printf "%04X:%04X\n", $segment, $offset
|
||||
end
|
||||
end
|
||||
document int_addr
|
||||
Get address of interruption
|
||||
end
|
||||
|
||||
define compute_regs
|
||||
set $rax = ((unsigned long)$eax & 0xFFFF)
|
||||
set $rbx = ((unsigned long)$ebx & 0xFFFF)
|
||||
set $rcx = ((unsigned long)$ecx & 0xFFFF)
|
||||
set $rdx = ((unsigned long)$edx & 0xFFFF)
|
||||
set $rsi = ((unsigned long)$esi & 0xFFFF)
|
||||
set $rdi = ((unsigned long)$edi & 0xFFFF)
|
||||
set $rbp = ((unsigned long)$ebp & 0xFFFF)
|
||||
set $rsp = ((unsigned long)$esp & 0xFFFF)
|
||||
set $rcs = ((unsigned long)$cs & 0xFFFF)
|
||||
set $rds = ((unsigned long)$ds & 0xFFFF)
|
||||
set $res = ((unsigned long)$es & 0xFFFF)
|
||||
set $rss = ((unsigned long)$ss & 0xFFFF)
|
||||
set $rip = ((((unsigned long)$cs & 0xFFFF) << 4) + ((unsigned long)$eip & 0xFFFF)) & $ADDRESS_MASK
|
||||
set $r_ss_sp = ((((unsigned long)$ss & 0xFFFF) << 4) + ((unsigned long)$esp & 0xFFFF)) & $ADDRESS_MASK
|
||||
set $r_ss_bp = ((((unsigned long)$ss & 0xFFFF) << 4) + ((unsigned long)$ebp & 0xFFFF)) & $ADDRESS_MASK
|
||||
end
|
||||
|
||||
define print_regs
|
||||
printf "AX: %04X BX: %04X ", $rax, $rbx
|
||||
printf "CX: %04X DX: %04X\n", $rcx, $rdx
|
||||
printf "SI: %04X DI: %04X ", $rsi, $rdi
|
||||
printf "SP: %04X BP: %04X\n", $rsp, $rbp
|
||||
printf "CS: %04X DS: %04X ", $rcs, $rds
|
||||
printf "ES: %04X SS: %04X\n", $res, $rss
|
||||
printf "\n"
|
||||
printf "IP: %04X EIP:%08X\n", ((unsigned short)$eip & 0xFFFF), $eip
|
||||
printf "CS:IP: %04X:%04X (0x%05X)\n", $rcs, ((unsigned short)$eip & 0xFFFF), $rip
|
||||
printf "SS:SP: %04X:%04X (0x%05X)\n", $rss, $rsp, $r_ss_sp
|
||||
printf "SS:BP: %04X:%04X (0x%05X)\n", $rss, $rbp, $r_ss_bp
|
||||
end
|
||||
document print_regs
|
||||
Print CPU registers
|
||||
end
|
||||
|
||||
define print_eflags
|
||||
printf "OF <%d> DF <%d> IF <%d> TF <%d>",\
|
||||
(($eflags >> 0xB) & 1), (($eflags >> 0xA) & 1), \
|
||||
(($eflags >> 9) & 1), (($eflags >> 8) & 1)
|
||||
printf " SF <%d> ZF <%d> AF <%d> PF <%d> CF <%d>\n",\
|
||||
(($eflags >> 7) & 1), (($eflags >> 6) & 1),\
|
||||
(($eflags >> 4) & 1), (($eflags >> 2) & 1), ($eflags & 1)
|
||||
printf "ID <%d> VIP <%d> VIF <%d> AC <%d>",\
|
||||
(($eflags >> 0x15) & 1), (($eflags >> 0x14) & 1), \
|
||||
(($eflags >> 0x13) & 1), (($eflags >> 0x12) & 1)
|
||||
printf " VM <%d> RF <%d> NT <%d> IOPL <%d>\n",\
|
||||
(($eflags >> 0x11) & 1), (($eflags >> 0x10) & 1),\
|
||||
(($eflags >> 0xE) & 1), (($eflags >> 0xC) & 3)
|
||||
end
|
||||
document print_eflags
|
||||
Print eflags register.
|
||||
end
|
||||
|
||||
# dump content of bytes in memory
|
||||
# arg0 : addr
|
||||
# arg1 : nb of bytes
|
||||
define _dump_memb
|
||||
if $argc < 2
|
||||
printf "Arguments: address number_of_bytes\n"
|
||||
else
|
||||
set $_nb = $arg1
|
||||
set $_i = 0
|
||||
set $_addr = $arg0
|
||||
while ($_i < $_nb)
|
||||
printf "%02X ", *((unsigned char*)$_addr + $_i)
|
||||
set $_i++
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# dump content of memory in words
|
||||
# arg0 : addr
|
||||
# arg1 : nb of words
|
||||
define _dump_memw
|
||||
if $argc < 2
|
||||
printf "Arguments: address number_of_words\n"
|
||||
else
|
||||
set $_nb = $arg1
|
||||
set $_i = 0
|
||||
set $_addr = $arg0
|
||||
while ($_i < $_nb)
|
||||
printf "%04X ", *((unsigned short*)$_addr + $_i)
|
||||
set $_i++
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# display data at given address
|
||||
define print_data
|
||||
if ($argc > 0)
|
||||
set $seg = $arg0
|
||||
set $off = $arg1
|
||||
set $raddr = ($arg0 << 16) + $arg1
|
||||
set $maddr = ($arg0 << 4) + $arg1
|
||||
|
||||
set $w = 16
|
||||
set $i = (int)0
|
||||
while ($i < 4)
|
||||
printf "%08X: ", ($raddr + $i * $w)
|
||||
set $j = (int)0
|
||||
while ($j < $w)
|
||||
printf "%02X ", *(unsigned char*)($maddr + $i * $w + $j)
|
||||
set $j++
|
||||
end
|
||||
printf " "
|
||||
set $j = (int)0
|
||||
while ($j < $w)
|
||||
set $c = *(unsigned char*)($maddr + $i * $w + $j)
|
||||
if ($c > 32) && ($c < 128)
|
||||
printf "%c", $c
|
||||
else
|
||||
printf "."
|
||||
end
|
||||
set $j++
|
||||
end
|
||||
printf "\n"
|
||||
set $i++
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
define context
|
||||
printf "---------------------------[ STACK ]---\n"
|
||||
_dump_memw $r_ss_sp 8
|
||||
printf "\n"
|
||||
set $_a = $r_ss_sp + 16
|
||||
_dump_memw $_a 8
|
||||
printf "\n"
|
||||
printf "---------------------------[ DS:SI ]---\n"
|
||||
print_data $ds $rsi
|
||||
printf "---------------------------[ ES:DI ]---\n"
|
||||
print_data $es $rdi
|
||||
|
||||
printf "----------------------------[ CPU ]----\n"
|
||||
print_regs
|
||||
print_eflags
|
||||
printf "---------------------------[ CODE ]----\n"
|
||||
|
||||
set $_code_size = $CODE_SIZE
|
||||
|
||||
# disassemble
|
||||
# first call x/i with an address
|
||||
# subsequent calls to x/i will increment address
|
||||
if ($_code_size > 0)
|
||||
x /i $rip
|
||||
set $_code_size--
|
||||
end
|
||||
while ($_code_size > 0)
|
||||
x /i
|
||||
set $_code_size--
|
||||
end
|
||||
end
|
||||
document context
|
||||
Print context window, i.e. regs, stack, ds:esi and disassemble cs:eip.
|
||||
end
|
||||
|
||||
define hook-stop
|
||||
compute_regs
|
||||
if ($SHOW_CONTEXT > 0)
|
||||
context
|
||||
end
|
||||
end
|
||||
document hook-stop
|
||||
!!! FOR INTERNAL USE ONLY - DO NOT CALL !!!
|
||||
end
|
||||
|
||||
# add a breakpoint on an interrupt
|
||||
define break_int
|
||||
set $offset = (unsigned short)*($arg0 * 4)
|
||||
set $segment = (unsigned short)*($arg0 * 4 + 2)
|
||||
|
||||
break *$offset
|
||||
end
|
||||
|
||||
define break_int_if_ah
|
||||
if ($argc < 2)
|
||||
printf "Arguments: INT_N AH\n"
|
||||
else
|
||||
set $addr = (unsigned short)*($arg0 * 4)
|
||||
set $segment = (unsigned short)*($arg0 * 4 + 2)
|
||||
break *$addr if ((unsigned long)$eax & 0xFF00) == ($arg1 << 8)
|
||||
end
|
||||
end
|
||||
document break_int_if_ah
|
||||
Install a breakpoint on INT N only if AH is equal to the expected value
|
||||
end
|
||||
|
||||
define break_int_if_ax
|
||||
if ($argc < 2)
|
||||
printf "Arguments: INT_N AX\n"
|
||||
else
|
||||
set $addr = (unsigned short)*($arg0 * 4)
|
||||
set $segment = (unsigned short)*($arg0 * 4 + 2)
|
||||
break *$addr if ((unsigned long)$eax & 0xFFFF) == $arg1
|
||||
end
|
||||
end
|
||||
document break_int_if_ax
|
||||
Install a breakpoint on INT N only if AX is equal to the expected value
|
||||
end
|
||||
|
||||
define stepo
|
||||
## we know that an opcode starting by 0xE8 has a fixed length
|
||||
## for the 0xFF opcodes, we can enumerate what is possible to have
|
||||
|
||||
set $lip = $rip
|
||||
set $offset = 0
|
||||
|
||||
# first, get rid of segment prefixes, if any
|
||||
set $_byte1 = *(unsigned char *)$rip
|
||||
# CALL DS:xx CS:xx, etc.
|
||||
if ($_byte1 == 0x3E || $_byte1 == 0x26 || $_byte1 == 0x2E || $_byte1 == 0x36 || $_byte1 == 0x3E || $_byte1 == 0x64 || $_byte1 == 0x65)
|
||||
set $lip = $rip + 1
|
||||
set $_byte1 = *(unsigned char*)$lip
|
||||
set $offset = 1
|
||||
end
|
||||
set $_byte2 = *(unsigned char *)($lip+1)
|
||||
set $_byte3 = *(unsigned char *)($lip+2)
|
||||
|
||||
set $noffset = 0
|
||||
|
||||
if ($_byte1 == 0xE8)
|
||||
# call near
|
||||
set $noffset = 3
|
||||
else
|
||||
if ($_byte1 == 0xFF)
|
||||
# A "ModR/M" byte follows
|
||||
set $_mod = ($_byte2 & 0xC0) >> 6
|
||||
set $_reg = ($_byte2 & 0x38) >> 3
|
||||
set $_rm = ($_byte2 & 7)
|
||||
#printf "mod: %d reg: %d rm: %d\n", $_mod, $_reg, $_rm
|
||||
|
||||
# only for CALL instructions
|
||||
if ($_reg == 2 || $_reg == 3)
|
||||
|
||||
# default offset
|
||||
set $noffset = 2
|
||||
|
||||
if ($_mod == 0)
|
||||
if ($_rm == 6)
|
||||
# a 16bit address follows
|
||||
set $noffset = 4
|
||||
end
|
||||
else
|
||||
if ($_mod == 1)
|
||||
# a 8bit displacement follows
|
||||
set $noffset = 3
|
||||
else
|
||||
if ($_mod == 2)
|
||||
# 16bit displacement
|
||||
set $noffset = 4
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
# end of _reg == 2 or _reg == 3
|
||||
|
||||
else
|
||||
# else byte1 != 0xff
|
||||
if ($_byte1 == 0x9A)
|
||||
# call far
|
||||
set $noffset = 5
|
||||
else
|
||||
if ($_byte1 == 0xCD)
|
||||
# INTERRUPT CASE
|
||||
set $noffset = 2
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
# end of byte1 == 0xff
|
||||
end
|
||||
# else byte1 != 0xe8
|
||||
|
||||
# if we have found a call to bypass we set a temporary breakpoint on next instruction and continue
|
||||
if ($noffset != 0)
|
||||
set $_nextaddress = $eip + $offset + $noffset
|
||||
printf "Setting BP to %04X\n", $_nextaddress
|
||||
tbreak *$_nextaddress
|
||||
continue
|
||||
# else we just single step
|
||||
else
|
||||
nexti
|
||||
end
|
||||
end
|
||||
document stepo
|
||||
Step over calls
|
||||
This function will set a temporary breakpoint on next instruction after the call so the call will be bypassed
|
||||
You can safely use it instead nexti since it will single step code if it's not a call instruction (unless you want to go into the call function)
|
||||
end
|
||||
|
||||
define step_until_iret
|
||||
set $SHOW_CONTEXT=0
|
||||
set $_found = 0
|
||||
while (!$_found)
|
||||
if (*(unsigned char*)$rip == 0xCF)
|
||||
set $_found = 1
|
||||
else
|
||||
stepo
|
||||
end
|
||||
end
|
||||
set $SHOW_CONTEXT=1
|
||||
context
|
||||
end
|
||||
|
||||
define step_until_ret
|
||||
set $SHOW_CONTEXT=0
|
||||
set $_found = 0
|
||||
while (!$_found)
|
||||
set $_p = *(unsigned char*)$rip
|
||||
if ($_p == 0xC3 || $_p == 0xCB || $_p == 0xC2 || $_p == 0xCA)
|
||||
set $_found = 1
|
||||
else
|
||||
stepo
|
||||
end
|
||||
end
|
||||
set $SHOW_CONTEXT=1
|
||||
context
|
||||
end
|
||||
|
||||
define step_until_int
|
||||
set $SHOW_CONTEXT = 0
|
||||
|
||||
while (*(unsigned char*)$rip != 0xCD)
|
||||
stepo
|
||||
end
|
||||
set $SHOW_CONTEXT = 1
|
||||
context
|
||||
end
|
||||
|
||||
# Find a pattern in memory
|
||||
# The pattern is given by a string as arg0
|
||||
# If another argument is present it gives the starting address (0 otherwise)
|
||||
define find_in_mem
|
||||
if ($argc >= 2)
|
||||
set $_addr = $arg1
|
||||
else
|
||||
set $_addr = 0
|
||||
end
|
||||
set $_found = 0
|
||||
set $_tofind = $arg0
|
||||
while ($_addr < $ADDRESS_MASK) && (!$_found)
|
||||
if ($_addr % 0x100 == 0)
|
||||
printf "%08X\n", $_addr
|
||||
end
|
||||
set $_i = 0
|
||||
set $_found = 1
|
||||
while ($_tofind[$_i] != 0 && $_found == 1)
|
||||
set $_b = *((char*)$_addr + $_i)
|
||||
set $_t = (char)$_tofind[$_i]
|
||||
if ($_t != $_b)
|
||||
set $_found = 0
|
||||
end
|
||||
set $_i++
|
||||
end
|
||||
if ($_found == 1)
|
||||
printf "Code found at 0x%05X\n", $_addr
|
||||
end
|
||||
set $_addr++
|
||||
end
|
||||
end
|
||||
document find_in_mem
|
||||
Find a pattern in memory
|
||||
The pattern is given by a string as arg0
|
||||
If another argument is present it gives the starting address (0 otherwise)
|
||||
end
|
||||
|
||||
|
||||
define step_until_code
|
||||
set $_tofind = $arg0
|
||||
set $SHOW_CONTEXT = 0
|
||||
|
||||
set $_found = 0
|
||||
while (!$_found)
|
||||
set $_i = 0
|
||||
set $_found = 1
|
||||
|
||||
while ($_tofind[$_i] != 0 && $_found == 1)
|
||||
set $_b = *((char*)$rip + $_i)
|
||||
set $_t = (char)$_tofind[$_i]
|
||||
if ($_t != $_b)
|
||||
set $_found = 0
|
||||
end
|
||||
set $_i++
|
||||
end
|
||||
|
||||
if ($_found == 0)
|
||||
stepo
|
||||
end
|
||||
end
|
||||
|
||||
set $SHOW_CONTEXT = 1
|
||||
context
|
||||
end
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
target remote localhost:1234
|
||||
set disassembly-flavor intel
|
||||
set architecture i8086
|
||||
display/20i $pc+$cs*16
|
||||
set tdesc filename ./debug/target.xml
|
||||
break *0x80010
|
||||
cont
|
||||
continue
|
||||
clear *0x80010
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- Copyright (C) 2010-2017 Free Software Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. -->
|
||||
|
||||
<!DOCTYPE target SYSTEM "gdb-target.dtd">
|
||||
<target>
|
||||
<architecture>i8086</architecture>
|
||||
<feature name="org.gnu.gdb.i386.core">
|
||||
<flags id="i386_eflags" size="4">
|
||||
<field name="CF" start="0" end="0"/>
|
||||
<field name="" start="1" end="1"/>
|
||||
<field name="PF" start="2" end="2"/>
|
||||
<field name="AF" start="4" end="4"/>
|
||||
<field name="ZF" start="6" end="6"/>
|
||||
<field name="SF" start="7" end="7"/>
|
||||
<field name="TF" start="8" end="8"/>
|
||||
<field name="IF" start="9" end="9"/>
|
||||
<field name="DF" start="10" end="10"/>
|
||||
<field name="OF" start="11" end="11"/>
|
||||
<field name="NT" start="14" end="14"/>
|
||||
<field name="RF" start="16" end="16"/>
|
||||
<field name="VM" start="17" end="17"/>
|
||||
<field name="AC" start="18" end="18"/>
|
||||
<field name="VIF" start="19" end="19"/>
|
||||
<field name="VIP" start="20" end="20"/>
|
||||
<field name="ID" start="21" end="21"/>
|
||||
</flags>
|
||||
|
||||
<reg name="eax" bitsize="32" type="int32"/>
|
||||
<reg name="ecx" bitsize="32" type="int32"/>
|
||||
<reg name="edx" bitsize="32" type="int32"/>
|
||||
<reg name="ebx" bitsize="32" type="int32"/>
|
||||
<reg name="esp" bitsize="32" type="data_ptr"/>
|
||||
<reg name="ebp" bitsize="32" type="data_ptr"/>
|
||||
<reg name="esi" bitsize="32" type="int32"/>
|
||||
<reg name="edi" bitsize="32" type="int32"/>
|
||||
|
||||
<reg name="eip" bitsize="32" type="code_ptr"/>
|
||||
<reg name="eflags" bitsize="32" type="i386_eflags"/>
|
||||
<reg name="cs" bitsize="32" type="int32"/>
|
||||
<reg name="ss" bitsize="32" type="int32"/>
|
||||
<reg name="ds" bitsize="32" type="int32"/>
|
||||
<reg name="es" bitsize="32" type="int32"/>
|
||||
<reg name="fs" bitsize="32" type="int32"/>
|
||||
<reg name="gs" bitsize="32" type="int32"/>
|
||||
|
||||
<reg name="st0" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st1" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st2" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st3" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st4" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st5" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st6" bitsize="80" type="i387_ext"/>
|
||||
<reg name="st7" bitsize="80" type="i387_ext"/>
|
||||
|
||||
<reg name="fctrl" bitsize="32" type="int" group="float"/>
|
||||
<reg name="fstat" bitsize="32" type="int" group="float"/>
|
||||
<reg name="ftag" bitsize="32" type="int" group="float"/>
|
||||
<reg name="fiseg" bitsize="32" type="int" group="float"/>
|
||||
<reg name="fioff" bitsize="32" type="int" group="float"/>
|
||||
<reg name="foseg" bitsize="32" type="int" group="float"/>
|
||||
<reg name="fooff" bitsize="32" type="int" group="float"/>
|
||||
<reg name="fop" bitsize="32" type="int" group="float"/>
|
||||
</feature>
|
||||
<feature name="org.gnu.gdb.i386.32bit.sse">
|
||||
<vector id="v4f" type="ieee_single" count="4"/>
|
||||
<vector id="v2d" type="ieee_double" count="2"/>
|
||||
<vector id="v16i8" type="int8" count="16"/>
|
||||
<vector id="v8i16" type="int16" count="8"/>
|
||||
<vector id="v4i32" type="int32" count="4"/>
|
||||
<vector id="v2i64" type="int64" count="2"/>
|
||||
<union id="vec128">
|
||||
<field name="v4_float" type="v4f"/>
|
||||
<field name="v2_double" type="v2d"/>
|
||||
<field name="v16_int8" type="v16i8"/>
|
||||
<field name="v8_int16" type="v8i16"/>
|
||||
<field name="v4_int32" type="v4i32"/>
|
||||
<field name="v2_int64" type="v2i64"/>
|
||||
<field name="uint128" type="uint128"/>
|
||||
</union>
|
||||
<flags id="i386_mxcsr" size="4">
|
||||
<field name="IE" start="0" end="0"/>
|
||||
<field name="DE" start="1" end="1"/>
|
||||
<field name="ZE" start="2" end="2"/>
|
||||
<field name="OE" start="3" end="3"/>
|
||||
<field name="UE" start="4" end="4"/>
|
||||
<field name="PE" start="5" end="5"/>
|
||||
<field name="DAZ" start="6" end="6"/>
|
||||
<field name="IM" start="7" end="7"/>
|
||||
<field name="DM" start="8" end="8"/>
|
||||
<field name="ZM" start="9" end="9"/>
|
||||
<field name="OM" start="10" end="10"/>
|
||||
<field name="UM" start="11" end="11"/>
|
||||
<field name="PM" start="12" end="12"/>
|
||||
<field name="FZ" start="15" end="15"/>
|
||||
</flags>
|
||||
|
||||
<reg name="xmm0" bitsize="128" type="vec128" regnum="32"/>
|
||||
<reg name="xmm1" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm2" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm3" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm4" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm5" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm6" bitsize="128" type="vec128"/>
|
||||
<reg name="xmm7" bitsize="128" type="vec128"/>
|
||||
|
||||
<reg name="mxcsr" bitsize="32" type="i386_mxcsr" group="vector"/>
|
||||
</feature>
|
||||
</target>
|
|
@ -61,17 +61,20 @@ struc ints ;bloc interruption
|
|||
.sizeof = $ - .number
|
||||
}
|
||||
|
||||
struc mb check,isnotlast,isresident,reference,sizes,names
|
||||
;Bloc de mémoire
|
||||
struc mb asize,aname ;Bloc de mémoire
|
||||
{
|
||||
.check db "NH" ;signature du bloc de mémoire.
|
||||
.isnotlast db 0 ;flag indiquant le dernier bloc
|
||||
.isresident db 0 ;flag indiquant que le bloc est resident
|
||||
.reference dw 0 ;pointeur vers le bloc parent
|
||||
.sizes dw 0 ;taille du bloc en paragraphe de 16 octet
|
||||
.names db 24 dup (0) ;nom du bloc
|
||||
.sizeof = $ - .check
|
||||
.sizes dw asize ;taille du bloc en paragraphe de 16 octet
|
||||
.names db aname ;nom du bloc
|
||||
.endofstr db 0
|
||||
.sizeof = 32
|
||||
}
|
||||
virtual at 0
|
||||
mb mb ?,?
|
||||
end virtual
|
||||
|
||||
struc exe major
|
||||
;Executable COS
|
||||
|
|
4
makefile
4
makefile
|
@ -31,10 +31,10 @@ debug: debug-system
|
|||
redebug: clean debug
|
||||
|
||||
debug-boot: all copy qemu-debug
|
||||
(sleep 2;cgdb -x ./debug/boot.txt)
|
||||
(sleep 2;gdb -ix ./debug/gdb_init_real_mode.txt -x ./debug/boot.txt)
|
||||
|
||||
debug-system: all copy qemu-debug
|
||||
(sleep 2;cgdb -x ./debug/system.txt)
|
||||
(sleep 2;gdb -ix ./debug/gdb_init_real_mode.txt -x ./debug/system.txt)
|
||||
|
||||
qemu-debug:
|
||||
(killall qemu-system-i386;qemu-system-i386 -m 1G -fda ./final/cos2000.img -s -S &)
|
||||
|
|
160
noyau/mcb.asm
160
noyau/mcb.asm
|
@ -134,12 +134,13 @@ firstmb dw 0
|
|||
|
||||
;Charge les sections du block %0
|
||||
proc mbloadsection uses ax bx cx si di ds es, blocks:word
|
||||
local toresov[200]:WORD
|
||||
mov ax,[blocks]
|
||||
mov es,ax
|
||||
mov ds,ax
|
||||
cmp word [0],"EC"
|
||||
jne .notace
|
||||
lea si,[.toresov]
|
||||
lea si,[toresov]
|
||||
mov word [ss:si],0FFFFh
|
||||
virtual at 0
|
||||
.exe exe
|
||||
|
@ -194,7 +195,6 @@ popad
|
|||
.depandserror:
|
||||
stc
|
||||
ret
|
||||
.toresov dw 60 dup (0)
|
||||
endp
|
||||
|
||||
|
||||
|
@ -209,10 +209,8 @@ proc mbinit uses ax cx si di ds es
|
|||
mov es,ax
|
||||
mov si,afree
|
||||
xor di,di
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
mov cx,.mb.sizeof
|
||||
mov cx,mb.sizeof
|
||||
cld
|
||||
rep movsb
|
||||
clc
|
||||
ret
|
||||
|
@ -221,8 +219,7 @@ proc mbinit uses ax cx si di ds es
|
|||
ret
|
||||
endp
|
||||
|
||||
afree mb "HN",0,0,0,0A000h-memorystart,"Libre"
|
||||
db 0
|
||||
afree mb 0A000h-memorystart,"Libre"
|
||||
|
||||
;Creér un bloc de nom %0 de taille %1 (octets) -> n°segment dans AX
|
||||
proc mbcreate uses bx cx dx si di ds es, blocks:word, size:word
|
||||
|
@ -248,23 +245,20 @@ proc mbcreate uses bx cx dx si di ds es, blocks:word, size:word
|
|||
cmp dl,false
|
||||
je .notenougtmem
|
||||
mov es,bx
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp word [es:.mb.check],"NH"
|
||||
cmp word [es:mb.check],"NH"
|
||||
jne .memoryerror
|
||||
cmp [es:.mb.isnotlast],true
|
||||
cmp [es:mb.isnotlast],true
|
||||
sete dl
|
||||
cmp [es:.mb.reference],free
|
||||
cmp [es:mb.reference],free
|
||||
jne .notsogood
|
||||
mov ax,[es:.mb.sizes]
|
||||
mov ax,[es:mb.sizes]
|
||||
cmp cx,ax
|
||||
ja .notsogood
|
||||
mov word [es:.mb.check],"NH"
|
||||
mov [es:.mb.isnotlast],true
|
||||
mov [es:.mb.reference],gs
|
||||
mov [es:.mb.isresident],false
|
||||
lea di,[es:.mb.names]
|
||||
mov word [es:mb.check],"NH"
|
||||
mov [es:mb.isnotlast],true
|
||||
mov [es:mb.reference],gs
|
||||
mov [es:mb.isresident],false
|
||||
lea di,[es:mb.names]
|
||||
push cx
|
||||
mov cx,24/4
|
||||
mov si,[blocks]
|
||||
|
@ -278,18 +272,18 @@ proc mbcreate uses bx cx dx si di ds es, blocks:word, size:word
|
|||
je .nofree
|
||||
dec ax
|
||||
dec ax
|
||||
mov [es:.mb.sizes],cx
|
||||
mov [es:mb.sizes],cx
|
||||
add cx,bx
|
||||
mov es,cx
|
||||
mov si,afree
|
||||
xor di,di
|
||||
mov cx,.mb.sizeof
|
||||
mov cx,mb.sizeof
|
||||
push cs
|
||||
pop ds
|
||||
cld
|
||||
rep movsb
|
||||
mov [es:.mb.isnotlast],dl
|
||||
mov [es:.mb.sizes],ax
|
||||
mov [es:mb.isnotlast],dl
|
||||
mov [es:mb.sizes],ax
|
||||
.nofree:
|
||||
mov ax,bx
|
||||
pop gs
|
||||
|
@ -298,7 +292,7 @@ proc mbcreate uses bx cx dx si di ds es, blocks:word, size:word
|
|||
.notsogood:
|
||||
inc bx
|
||||
inc bx
|
||||
add bx,[es:.mb.sizes]
|
||||
add bx,[es:mb.sizes]
|
||||
jmp .searchfree
|
||||
.memoryerror:
|
||||
pop gs
|
||||
|
@ -317,20 +311,17 @@ proc mbfree uses ax bx cx si di ds es, blocks:word
|
|||
dec bx
|
||||
dec bx
|
||||
mov es,bx
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp word [es:.mb.check],"NH"
|
||||
cmp word [es:mb.check],"NH"
|
||||
jne .memoryerror
|
||||
cmp [es:.mb.reference],free
|
||||
cmp [es:mb.reference],free
|
||||
je .wasfree
|
||||
cmp [es:.mb.isresident],true
|
||||
cmp [es:mb.isresident],true
|
||||
je .wasresident
|
||||
mov [es:.mb.reference],free
|
||||
mov [es:mb.reference],free
|
||||
push cs
|
||||
pop ds
|
||||
mov si,.isfree
|
||||
lea di,[es:.mb.names]
|
||||
lea di,[es:mb.names]
|
||||
mov cx,6
|
||||
cld
|
||||
rep movsb
|
||||
|
@ -339,24 +330,24 @@ proc mbfree uses ax bx cx si di ds es, blocks:word
|
|||
dec bx
|
||||
.searchtofree:
|
||||
mov es,bx
|
||||
cmp word [es:.mb.check],"NH"
|
||||
cmp word [es:mb.check],"NH"
|
||||
jne .memoryerror
|
||||
inc bx
|
||||
inc bx
|
||||
add bx,[es:.mb.sizes]
|
||||
cmp [es:.mb.sizes],0
|
||||
add bx,[es:mb.sizes]
|
||||
cmp [es:mb.sizes],0
|
||||
je .nottofree
|
||||
cmp ax,[es:.mb.reference]
|
||||
cmp ax,[es:mb.reference]
|
||||
jne .nottofree
|
||||
mov [es:.mb.isresident],false
|
||||
mov [es:.mb.reference],free
|
||||
mov [es:mb.isresident],false
|
||||
mov [es:mb.reference],free
|
||||
mov si,.isfree
|
||||
lea di,[es:.mb.names]
|
||||
lea di,[es:mb.names]
|
||||
mov cx,6
|
||||
cld
|
||||
rep movsb
|
||||
.nottofree:
|
||||
cmp [es:.mb.isnotlast],true
|
||||
cmp [es:mb.isnotlast],true
|
||||
je .searchtofree
|
||||
stdcall mbclean
|
||||
ret
|
||||
|
@ -382,23 +373,20 @@ proc mbclean uses ax bx dx es gs
|
|||
xor dx,dx
|
||||
.searchfree:
|
||||
mov gs,bx
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp word [gs:.mb.check],"NH"
|
||||
cmp word [gs:mb.check],"NH"
|
||||
jne .memoryerror
|
||||
inc bx
|
||||
inc bx
|
||||
add bx,[gs:.mb.sizes]
|
||||
cmp word [gs:.mb.sizes],0
|
||||
add bx,[gs:mb.sizes]
|
||||
cmp word [gs:mb.sizes],0
|
||||
je .notenougtmem
|
||||
cmp [gs:.mb.reference],free
|
||||
cmp [gs:mb.reference],free
|
||||
jne .notfree
|
||||
cmp ax,0
|
||||
je .notmeetfree
|
||||
add dx,[gs:.mb.sizes]
|
||||
mov word [gs:.mb.check],0
|
||||
mov dword [gs:.mb.names],0
|
||||
add dx,[gs:mb.sizes]
|
||||
mov word [gs:mb.check],0
|
||||
mov dword [gs:mb.names],0
|
||||
inc dx
|
||||
inc dx
|
||||
jmp .nottrigered
|
||||
|
@ -410,16 +398,16 @@ proc mbclean uses ax bx dx es gs
|
|||
cmp ax,0
|
||||
je .nottrigered
|
||||
mov es,ax
|
||||
add [es:.mb.sizes],dx
|
||||
add [es:mb.sizes],dx
|
||||
xor ax,ax
|
||||
.nottrigered:
|
||||
cmp [gs:.mb.isnotlast],true
|
||||
cmp [gs:mb.isnotlast],true
|
||||
je .searchfree
|
||||
cmp ax,0
|
||||
je .reallyfinish
|
||||
mov es,ax
|
||||
add [es:.mb.sizes],dx
|
||||
mov [es:.mb.isnotlast],false
|
||||
add [es:mb.sizes],dx
|
||||
mov [es:mb.isnotlast],false
|
||||
.reallyfinish:
|
||||
clc
|
||||
ret
|
||||
|
@ -437,12 +425,9 @@ proc mbresident uses bx es, blocks:word
|
|||
dec bx
|
||||
dec bx
|
||||
mov es,bx
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp word [es:.mb.check],"NH"
|
||||
cmp word [es:mb.check],"NH"
|
||||
jne .memoryerror
|
||||
mov [es:.mb.isresident],true
|
||||
mov [es:mb.isresident],true
|
||||
ret
|
||||
.memoryerror:
|
||||
stc
|
||||
|
@ -455,12 +440,9 @@ proc mbnonresident uses bx es, blocks:word
|
|||
dec bx
|
||||
dec bx
|
||||
mov es,bx
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp word [es:.mb.check],"NH"
|
||||
cmp word [es:mb.check],"NH"
|
||||
jne .memoryerror
|
||||
mov [es:.mb.isresident],false
|
||||
mov [es:mb.isresident],false
|
||||
ret
|
||||
.memoryerror:
|
||||
stc
|
||||
|
@ -474,15 +456,12 @@ proc mbchown uses bx dx es,blocks:word, owner:word
|
|||
dec bx
|
||||
dec bx
|
||||
mov es,bx
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp word [es:.mb.check],"NH"
|
||||
cmp word [es:mb.check],"NH"
|
||||
jne .memoryerror
|
||||
cmp [es:.mb.reference],free
|
||||
cmp [es:mb.reference],free
|
||||
je .wasfree
|
||||
mov dx,[owner]
|
||||
mov [es:.mb.reference],dx
|
||||
mov [es:mb.reference],dx
|
||||
ret
|
||||
.memoryerror:
|
||||
stc
|
||||
|
@ -511,21 +490,18 @@ proc mbget uses bx dx es, num:word
|
|||
xor dx,dx
|
||||
.searchfree:
|
||||
mov es,bx
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp word [es:.mb.check],"NH"
|
||||
cmp word [es:mb.check],"NH"
|
||||
jne .memoryerror
|
||||
inc bx
|
||||
inc bx
|
||||
add bx,[es:.mb.sizes]
|
||||
cmp [es:.mb.sizes],0
|
||||
add bx,[es:mb.sizes]
|
||||
cmp [es:mb.sizes],0
|
||||
je .memoryerror
|
||||
cmp dx,[num]
|
||||
je .foundmcb
|
||||
ja .notfound
|
||||
inc dx
|
||||
cmp [es:.mb.isnotlast],true
|
||||
cmp [es:mb.isnotlast],true
|
||||
je .searchfree
|
||||
.memoryerror:
|
||||
stc
|
||||
|
@ -549,16 +525,13 @@ proc mbfind uses bx si di es, blocks:word
|
|||
mov si,[blocks]
|
||||
.search:
|
||||
mov es,bx
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
lea di,[es:.mb.names]
|
||||
cmp word [es:.mb.check],"NH"
|
||||
lea di,[es:mb.names]
|
||||
cmp word [es:mb.check],"NH"
|
||||
jne .memoryerror
|
||||
inc bx
|
||||
inc bx
|
||||
add bx,[es:.mb.sizes]
|
||||
cmp [es:.mb.sizes],0
|
||||
add bx,[es:mb.sizes]
|
||||
cmp [es:mb.sizes],0
|
||||
je .memoryerror
|
||||
push si di
|
||||
.cmpnames:
|
||||
|
@ -573,7 +546,7 @@ proc mbfind uses bx si di es, blocks:word
|
|||
.ok:
|
||||
pop di si
|
||||
je .foundmcb
|
||||
cmp [es:.mb.isnotlast],true
|
||||
cmp [es:mb.isnotlast],true
|
||||
je .search
|
||||
.notfound:
|
||||
stc
|
||||
|
@ -596,19 +569,16 @@ proc mbfindsb uses bx dx si di es, blocks:word, owner:word
|
|||
dec bx
|
||||
dec bx
|
||||
mov si,[blocks]
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
lea di,[es:.mb.names]
|
||||
lea di,[es:mb.names]
|
||||
mov dx,[owner]
|
||||
.search:
|
||||
mov es,bx
|
||||
cmp word [es:.mb.check],"NH"
|
||||
cmp word [es:mb.check],"NH"
|
||||
jne .memoryerror
|
||||
inc bx
|
||||
inc bx
|
||||
add bx,[es:.mb.sizes]
|
||||
cmp [es:.mb.sizes],0
|
||||
add bx,[es:mb.sizes]
|
||||
cmp [es:mb.sizes],0
|
||||
je .memoryerror
|
||||
push si di
|
||||
.cmpnames:
|
||||
|
@ -623,10 +593,10 @@ proc mbfindsb uses bx dx si di es, blocks:word, owner:word
|
|||
.ok:
|
||||
pop di si
|
||||
jne .notfoundmcb
|
||||
cmp [es:.mb.reference],dx
|
||||
cmp [es:mb.reference],dx
|
||||
je .foundmcb
|
||||
.notfoundmcb:
|
||||
cmp [es:.mb.isnotlast],true
|
||||
cmp [es:mb.isnotlast],true
|
||||
je .search
|
||||
.notfound:
|
||||
stc
|
||||
|
|
|
@ -455,9 +455,6 @@ showbuffers db '\l\c02Contenu des tampons disquette\l\l\c07'
|
|||
diskbuffers diskbuffer
|
||||
|
||||
code_dump:
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
invoke gettypeditem,di,0,' '
|
||||
invoke mbfind,di
|
||||
jc notmbfind
|
||||
|
@ -472,10 +469,7 @@ code_dump:
|
|||
notace2:
|
||||
push non
|
||||
suitelikeace2:
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp word [gs:.mb.isnotlast],true
|
||||
cmp word [gs:mb.isnotlast],true
|
||||
je notlast2
|
||||
push oui ;CE? str0 2
|
||||
jmp suitelikelast2
|
||||
|
@ -485,29 +479,20 @@ suitelikelast2:
|
|||
mov dx,gs
|
||||
push edx ;Emplacement memoire hex 2
|
||||
;parent
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp [gs:.mb.reference],0
|
||||
cmp [gs:mb.reference],0
|
||||
jne nextdetect2
|
||||
push cs
|
||||
push none ;parent lstr0 2x2
|
||||
add bx,[gs:.mb.sizes]
|
||||
add bx,[gs:mb.sizes]
|
||||
jmp suitemn2
|
||||
nextdetect2:
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
mov dx,[gs:.mb.reference]
|
||||
mov dx,[gs:mb.reference]
|
||||
dec dx
|
||||
dec dx
|
||||
push dx ;parent lstr0 2x2
|
||||
push .mb.names
|
||||
push mb.names
|
||||
suitemn2:
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp [gs: .mb.isresident],true
|
||||
cmp [gs: mb.isresident],true
|
||||
jne notresident2
|
||||
push oui ;resident str0 2
|
||||
jmp suitelistmcb2
|
||||
|
@ -515,14 +500,11 @@ notresident2:
|
|||
push non ;resident str0 2
|
||||
suitelistmcb2:
|
||||
xor edx,edx
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
mov dx,[gs:.mb.sizes]
|
||||
mov dx,[gs:mb.sizes]
|
||||
shl edx,4
|
||||
push edx
|
||||
push gs ;nom lstr0 2x2
|
||||
push .mb.names
|
||||
push mb.names
|
||||
push dumpshow ;ligne
|
||||
invoke print
|
||||
cmp word [fs:0x0],'EC'
|
||||
|
@ -1037,29 +1019,20 @@ suitelikeace:
|
|||
mov dx,fs
|
||||
push edx ;Emplacement memoire hex 2
|
||||
;parent
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp [gs:.mb.reference],0
|
||||
cmp [gs:mb.reference],0
|
||||
jne nextdetect
|
||||
push cs
|
||||
push none ;parent lstr0 2x2
|
||||
add bx,[gs:.mb.sizes]
|
||||
add bx,[gs:mb.sizes]
|
||||
jmp suitemn
|
||||
nextdetect:
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
mov dx,[gs:.mb.reference]
|
||||
mov dx,[gs:mb.reference]
|
||||
dec dx
|
||||
dec dx
|
||||
push dx ;parent lstr0 2x2
|
||||
push .mb.names
|
||||
push mb.names
|
||||
suitemn:
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
cmp [gs: .mb.isresident],true
|
||||
cmp [gs: mb.isresident],true
|
||||
jne notresident
|
||||
push oui ;resident str0 2
|
||||
jmp suitelistmcb
|
||||
|
@ -1067,15 +1040,12 @@ notresident:
|
|||
push non ;resident str0 2
|
||||
suitelistmcb:
|
||||
xor edx,edx
|
||||
virtual at 0
|
||||
.mb mb
|
||||
end virtual
|
||||
mov dx,[gs: .mb.sizes]
|
||||
mov dx,[gs: mb.sizes]
|
||||
shl edx,4
|
||||
push 6 ;decimal 4 + type 2
|
||||
push edx
|
||||
push gs ;nom lstr0 2x2
|
||||
push .mb.names
|
||||
push mb.names
|
||||
push line2 ;ligne
|
||||
invoke print
|
||||
jmp listmcb
|
||||
|
|
Loading…
Reference in New Issue