diff --git a/playground/AsmBreak.asm b/playground/AsmBreak.asm index 43349700..cd7ec8f4 100644 --- a/playground/AsmBreak.asm +++ b/playground/AsmBreak.asm @@ -27,6 +27,7 @@ ; ComReadEAX() ; Save EIP of the break ; .AsmBreakEIP = EAX + Mov DWORD [DebugStub_Var_AsmBreakEIP], EAX ; EDI = EAX Mov EDI, EAX @@ -34,6 +35,7 @@ ; AL = [EDI] Mov AL, BYTE [EDI] ; .AsmOrigByte = AL + Mov BYTE [DebugStub_Var_AsmOrigByte], AL ; Inject INT3 ; Do in 2 steps to force a byte move to RAM (till X# can do byte in one step) @@ -56,6 +58,7 @@ Mov BYTE [EDI], AL ; .AsmBreakEIP = 0 + Mov DWORD [DebugStub_Var_AsmBreakEIP], 0x0 ; } ; function SetINT1_TrapFLAG { diff --git a/playground/CmdMisc.asm b/playground/CmdMisc.asm index fc4addc5..d651bf96 100644 --- a/playground/CmdMisc.asm +++ b/playground/CmdMisc.asm @@ -10,9 +10,11 @@ ; function TraceOn { ; Tracing.On ; .TraceMode = 1 + Mov DWORD [DebugStub_Var_TraceMode], 0x1 ; } ; function TraceOff { ; Tracing.Off ; .TraceMode = 0 + Mov DWORD [DebugStub_Var_TraceMode], 0x0 ; } diff --git a/playground/CmdProcess.asm b/playground/CmdProcess.asm index f7d82384..5402f2aa 100644 --- a/playground/CmdProcess.asm +++ b/playground/CmdProcess.asm @@ -19,6 +19,7 @@ Mov EAX, 0x0 ; ComReadAL() ; .CommandID = EAX + Mov DWORD [DebugStub_Var_CommandID], EAX ; Get AL back so we can compare it, but also leave it for later ; EAX = [ESP] diff --git a/playground/CmdSend.asm b/playground/CmdSend.asm index a97194ae..23153236 100644 --- a/playground/CmdSend.asm +++ b/playground/CmdSend.asm @@ -13,11 +13,11 @@ ; ComWriteX() ; ESI = @.CallerESP - Mov ESI, DebugStub_Const_CallerESP + Mov ESI, DebugStub_Var_CallerESP ; ComWrite32() ; ESI = @.CallerEIP - Mov ESI, DebugStub_Const_CallerEIP + Mov ESI, DebugStub_Var_CallerEIP ; ComWrite32() ; } @@ -184,7 +184,7 @@ ; Send Calling EIP. ; ESI = @.CallerEIP - Mov ESI, DebugStub_Const_CallerEIP + Mov ESI, DebugStub_Var_CallerEIP ; ComWrite32() ; } @@ -404,7 +404,7 @@ Mov EBP, ESP ; pointer value ; ESI = @.CallerEIP - Mov ESI, DebugStub_Const_CallerEIP + Mov ESI, DebugStub_Var_CallerEIP ; ComWrite32() ; } @@ -419,7 +419,7 @@ Mov EBP, ESP ; pointer value ; ESI = @.CallerEIP - Mov ESI, DebugStub_Const_CallerEIP + Mov ESI, DebugStub_Var_CallerEIP ; ComWrite32() ; } @@ -451,7 +451,7 @@ Mov EBP, ESP ; pointer value ; ESI = @.CallerEIP - Mov ESI, DebugStub_Const_CallerEIP + Mov ESI, DebugStub_Var_CallerEIP ; ComWrite32() ; } @@ -501,15 +501,15 @@ Mov EBP, ESP ; +ESI Push ESI ; EAX = @.CallerEBP - Mov EAX, DebugStub_Const_CallerEBP + Mov EAX, DebugStub_Var_CallerEBP ; +EAX Push EAX ; EAX = @.CallerEIP - Mov EAX, DebugStub_Const_CallerEIP + Mov EAX, DebugStub_Var_CallerEIP ; +EAX Push EAX ; EAX = @.CallerESP - Mov EAX, DebugStub_Const_CallerESP + Mov EAX, DebugStub_Var_CallerESP ; +EAX Push EAX ; ECX = 36 diff --git a/playground/DebugStub.asm b/playground/DebugStub.asm index 6e5821ff..5bd2f1c9 100644 --- a/playground/DebugStub.asm +++ b/playground/DebugStub.asm @@ -46,7 +46,7 @@ ; Calculate location in table ; Mov [EBX + EAX * 4], ECX would be better, but our X# doesn't handle this yet ; EBX = @.DebugBPs - Mov EBX, DebugStub_Const_DebugBPs + Mov EBX, DebugStub_Var_DebugBPs ; EAX << 2 ; EBX += EAX @@ -92,7 +92,7 @@ ; Load the current BP Id we are testing against ; EBX = @.DebugBPs - Mov EBX, DebugStub_Const_DebugBPs + Mov EBX, DebugStub_Var_DebugBPs ; EAX = ECX Mov EAX, ECX ; 4 bytes per Id @@ -112,6 +112,7 @@ ; ECX++ Inc ECX ; .MaxBPId = ECX + Mov DWORD [DebugStub_Var_MaxBPId], ECX ; goto Continue ; } ; Has our count reached 0? If so, exit the loop as no BPs found... @@ -124,6 +125,7 @@ ; No BPs found ; 0 indicates no BPs - see comment above ; .MaxBPId = 0 + Mov DWORD [DebugStub_Var_MaxBPId], 0x0 ; Continue: ; Exit: @@ -219,7 +221,7 @@ ; EAX = .CallerEIP Mov EAX, DWORD [DebugStub_Var_CallerEIP] ; EDI = @.DebugBPs - Mov EDI, DebugStub_Const_DebugBPs + Mov EDI, DebugStub_Var_DebugBPs ; ECX = .MaxBPId Mov ECX, DWORD [DebugStub_Var_MaxBPId] ; //! repne scasd @@ -293,9 +295,12 @@ ; Reset request in case we are currently responding to one or we hit a fixed breakpoint ; before our request could be serviced (if one existed) ; .DebugBreakOnNextTrace = #StepTrigger_None + Mov [DebugStub_Var_DebugBreakOnNextTrace], DebugStub_Const_StepTrigger_None ; .BreakEBP = 0 + Mov DWORD [DebugStub_Var_BreakEBP], 0x0 ; Set break status ; .DebugStatus = #Status_Break + Mov [DebugStub_Var_DebugStatus], DebugStub_Const_Status_Break ; SendTrace() ; Wait for a command @@ -321,24 +326,30 @@ ; if AL = #Vs2Ds_StepInto { ; .DebugBreakOnNextTrace = #StepTrigger_Into + Mov [DebugStub_Var_DebugBreakOnNextTrace], DebugStub_Const_StepTrigger_Into ; Not used, but set for consistency ; .BreakEBP = EAX + Mov DWORD [DebugStub_Var_BreakEBP], EAX ; goto Done ; } ; if AL = #Vs2Ds_StepOver { ; .DebugBreakOnNextTrace = #StepTrigger_Over + Mov [DebugStub_Var_DebugBreakOnNextTrace], DebugStub_Const_StepTrigger_Over ; EAX = .CallerEBP Mov EAX, DWORD [DebugStub_Var_CallerEBP] ; .BreakEBP = EAX + Mov DWORD [DebugStub_Var_BreakEBP], EAX ; goto Done ; } ; if AL = #Vs2Ds_StepOut { ; .DebugBreakOnNextTrace = #StepTrigger_Out + Mov [DebugStub_Var_DebugBreakOnNextTrace], DebugStub_Const_StepTrigger_Out ; EAX = .CallerEBP Mov EAX, DWORD [DebugStub_Var_CallerEBP] ; .BreakEBP = EAX + Mov DWORD [DebugStub_Var_BreakEBP], EAX ; goto Done ; } @@ -348,5 +359,6 @@ ; Done: ; AckCommand() ; .DebugStatus = #Status_Run + Mov [DebugStub_Var_DebugStatus], DebugStub_Const_Status_Run ; } diff --git a/playground/Screen.asm b/playground/Screen.asm index 4d507d07..dfadd122 100644 --- a/playground/Screen.asm +++ b/playground/Screen.asm @@ -30,7 +30,7 @@ ; function DisplayWaitMsg { ; ESI = @.DebugWaitMsg - Mov ESI, DebugStub_Const_DebugWaitMsg + Mov ESI, DebugStub_Var_DebugWaitMsg ; EDI = #VidBase Mov EDI, DebugStub_Const_VidBase diff --git a/playground/Test.asm b/playground/Test.asm index bb1298ed..4824beab 100644 --- a/playground/Test.asm +++ b/playground/Test.asm @@ -1,4 +1,10 @@ ; namespace DebugStub -; [AX + 12] = EAX -Mov DWORD [AX + 12], EAX +; .v1 = 1 +Mov DWORD [DebugStub_Var_v1], 0x1 +; .v1 = AL +Mov BYTE [DebugStub_Var_v1], AL +; .v1 = EAX +Mov DWORD [DebugStub_Var_v1], EAX +; .v1 = #const +Mov [DebugStub_Var_v1], DebugStub_Const_const diff --git a/playground/Test.xs b/playground/Test.xs index bb8dce42..1e1f2428 100644 --- a/playground/Test.xs +++ b/playground/Test.xs @@ -1,3 +1,6 @@ namespace DebugStub -[AX + 12] = EAX +.v1 = 1 +.v1 = AL +.v1 = EAX +.v1 = #const diff --git a/playground/TracerEntry.asm b/playground/TracerEntry.asm index b1f46184..70b77ef6 100644 --- a/playground/TracerEntry.asm +++ b/playground/TracerEntry.asm @@ -29,7 +29,9 @@ cli PushAD ; Save current ESP so we can look at the results of PushAll later ; .PushAllPtr = ESP +Mov DWORD [DebugStub_Var_PushAllPtr], ESP ; .CallerEBP = EBP +Mov DWORD [DebugStub_Var_CallerEBP], EBP ; Get current ESP and add 32. This will skip over the PushAll and point ; us at the call data from Int3. @@ -43,6 +45,7 @@ Mov EAX, DWORD [EBP] ; 12 bytes for EFLAGS, CS, EIP ; EBP += 12 ; .CallerESP = EBP +Mov DWORD [DebugStub_Var_CallerESP], EBP ; EIP is pointer to op after our call. Int3 is 1 byte so we subtract 1. ; Note - when we used call it was 5 (size of our call + address) @@ -64,6 +67,7 @@ Mov EAX, EBX ; Store it for later use. ; .CallerEIP = EAX +Mov DWORD [DebugStub_Var_CallerEIP], EAX ; Executing() diff --git a/playground/Utilities.asm b/playground/Utilities.asm index e1695bdb..3cca3fa8 100644 --- a/playground/Utilities.asm +++ b/playground/Utilities.asm @@ -15,6 +15,7 @@ ; EAX = [ESP] Mov EAX, DWORD [ESP] ; .CallerEIP = EAX + Mov DWORD [DebugStub_Var_CallerEIP], EAX ; SendStackCorruptionOccurred() ; halt: ; goto halt diff --git a/source/XSharp.x86/Assemblers/NASM.cs b/source/XSharp.x86/Assemblers/NASM.cs index c47d9b4a..d1cf54a9 100644 --- a/source/XSharp.x86/Assemblers/NASM.cs +++ b/source/XSharp.x86/Assemblers/NASM.cs @@ -52,6 +52,11 @@ public NASM(TextWriter aOut) Add(OpCode.Mov, "{0} {1}, {2}", typeof(Size), typeof(RegisterAddress), typeof(Reg32)); Add(OpCode.Mov, "{0} {1}, {2}", typeof(Size), typeof(RegisterAddress), typeof(Identifier)); Add(OpCode.Mov, "{0} {1}, 0x{2:X}", typeof(Size), typeof(RegisterAddress), typeof(i32u)); + Add(OpCode.Mov, "{0} {1}, 0x{2:X}", typeof(Size), typeof(MemoryAddress), typeof(i32u)); + Add(OpCode.Mov, "{0} {1}, {2}", typeof(Size), typeof(MemoryAddress), typeof(Reg08)); + Add(OpCode.Mov, "{0} {1}, {2}", typeof(Size), typeof(MemoryAddress), typeof(Reg16)); + Add(OpCode.Mov, "{0} {1}, {2}", typeof(Size), typeof(MemoryAddress), typeof(Reg32)); + Add(OpCode.Mov, "{0}, {1}", typeof(MemoryAddress), typeof(Identifier)); Add(OpCode.Mov, "{0}, {1}", typeof(Reg08), typeof(Identifier)); Add(OpCode.Mov, "{0}, {1}", typeof(Reg16), typeof(Identifier)); Add(OpCode.Mov, "{0}, {1}", typeof(Reg32), typeof(Identifier)); diff --git a/source/XSharp/Emitters/AllEmitters.cs b/source/XSharp/Emitters/AllEmitters.cs index 66935026..177c2ff9 100644 --- a/source/XSharp/Emitters/AllEmitters.cs +++ b/source/XSharp/Emitters/AllEmitters.cs @@ -18,13 +18,7 @@ public AllEmitters(Compiler aCompiler, x86.Assemblers.Assembler aAsm) : base(aCo // =============================================================== - [Emitter(typeof(Variable), typeof(OpEquals), typeof(Int08u))] - [Emitter(typeof(Variable), typeof(OpEquals), typeof(Int16u))] - [Emitter(typeof(Variable), typeof(OpEquals), typeof(Int32u))] [Emitter(typeof(Variable), typeof(OpEquals), typeof(Variable))] - [Emitter(typeof(Variable), typeof(OpEquals), typeof(VariableAddress))] - [Emitter(typeof(Variable), typeof(OpEquals), typeof(Const))] - [Emitter(typeof(Variable), typeof(OpEquals), typeof(Reg))] protected void VariableAssignment(object aVariableName, string aOpEquals, object aValue) { } diff --git a/source/XSharp/Emitters/Assignments.cs b/source/XSharp/Emitters/Assignments.cs index 9d2eabc6..f3710d4b 100644 --- a/source/XSharp/Emitters/Assignments.cs +++ b/source/XSharp/Emitters/Assignments.cs @@ -1,5 +1,4 @@ -using System; -using Spruce.Attribs; +using Spruce.Attribs; using Spruce.Tokens; using XSharp.Tokens; using XSharp.x86; @@ -8,7 +7,6 @@ using Reg08 = XSharp.Tokens.Reg08; using Reg16 = XSharp.Tokens.Reg16; using Reg32 = XSharp.Tokens.Reg32; -using Size = XSharp.x86.Params.Size; namespace XSharp.Emitters { @@ -86,7 +84,7 @@ protected void RegAssigVar(Register aReg, string aEquals, Address aVal) [Emitter(typeof(Reg), typeof(OpEquals), typeof(VariableAddress))] protected void RegAssignVarAddr(Register aReg, string aEquals, string aVal) { - Asm.Emit(OpCode.Mov, aReg, $"{Compiler.GetPrefixForConst}{aVal}"); + Asm.Emit(OpCode.Mov, aReg, $"{Compiler.GetPrefixForVar}{aVal}"); } // ESI = [EBP-1] => mov ESI, dword [EBP - 1] @@ -112,5 +110,32 @@ protected void RegAssignToMemory(string aOpOpenBracket, Register aTargetRegister { Asm.Emit(OpCode.Mov, source.RegSize, new Address(aTargetRegisterRoot, aOffset, aOpOperator == "-"), source); } + + // .v1 = 1 => mov dword [v1], 0x1 + [Emitter(typeof(Variable), typeof(OpEquals), typeof(Int32u))] + [Emitter(typeof(Variable), typeof(OpEquals), typeof(Reg))] + [Emitter(typeof(Variable), typeof(OpEquals), typeof(Const))] + protected void VariableAssignment(Address aVariableName, string aOpEquals, object aValue) + { + string size; + switch (aValue) + { + case uint _: + size = "dword"; + Asm.Emit(OpCode.Mov, size, aVariableName.AddPrefix(Compiler.GetPrefixForVar), aValue); + break; + + case Register aValueReg: + size = aValueReg.RegSize; + Asm.Emit(OpCode.Mov, size, aVariableName.AddPrefix(Compiler.GetPrefixForVar), aValue); + break; + + case string _: + //TODO: verify this + aValue = $"{Compiler.GetPrefixForConst}{aValue}"; + Asm.Emit(OpCode.Mov, aVariableName.AddPrefix(Compiler.GetPrefixForVar), aValue); + break; + } + } } } diff --git a/source/XSharp/ToDo.txt b/source/XSharp/ToDo.txt index ca0ea0e5..13134b27 100644 --- a/source/XSharp/ToDo.txt +++ b/source/XSharp/ToDo.txt @@ -20,6 +20,9 @@ IfPredicate - { and return - goto has value. Can compound front intead wtih comp -Live input to pl0ay and graph path -Generate attrib signature, and also optionally empty method with args +-Assignments.cs + - Check generation of var = const. + Kudzu ---------------------------------------------------- *** PrivateAssets to G3 Enrique 500