Skip to content

Commit 6ce6d8d

Browse files
Merge pull request #10 from tathanhdinh/show_opcodes
Add option to show instruction opcodes
2 parents f197181 + a350d45 commit 6ce6d8d

File tree

3 files changed

+26
-17
lines changed

3 files changed

+26
-17
lines changed

src/fasmi/Disassembly.fs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ let formatterOptions = FormatterOptions(
7676

7777

7878
// disassemble a single method
79-
let disassembleConcreteMethod (runtime: ClrRuntime) (mthinfo: MethodBase) platform (writer: TextWriter) =
79+
let disassembleConcreteMethod (runtime: ClrRuntime) (mthinfo: MethodBase) platform showOpcodes (writer: TextWriter) =
8080

8181
runtime.FlushCachedData()
8282
let h = mthinfo.MethodHandle
@@ -139,7 +139,13 @@ let disassembleConcreteMethod (runtime: ClrRuntime) (mthinfo: MethodBase) platfo
139139
// render instructions
140140
for inst in decoder do
141141
formatter.Format(&inst, out)
142-
writer.WriteLine $"L%04x{inst.IP - address}: %s{out.ToStringAndReset()}"
142+
let inst_relative_ip = int <| inst.IP - address
143+
if showOpcodes then
144+
let inst_opcode_hex = bytes[inst_relative_ip..inst_relative_ip + inst.Length - 1]
145+
|> Array.fold (fun hex b -> sprintf "%s %02x" hex b) ""
146+
writer.WriteLine $"L%04x{inst_relative_ip}: %45s{inst_opcode_hex} %s{out.ToStringAndReset()}"
147+
else
148+
writer.WriteLine $"L%04x{inst_relative_ip}: %s{out.ToStringAndReset()}"
143149
writer.Flush()
144150

145151

@@ -153,9 +159,9 @@ let outputGenericMethod (runtime: ClrRuntime) (mthinfo: MethodBase) (writer: Tex
153159
writer.WriteLine $"; generic method cannot be jitted. provide explicit types"
154160
writer.Flush()
155161

156-
let disassembleMethod runtime (mthinfo: MethodBase) platform writer =
162+
let disassembleMethod runtime (mthinfo: MethodBase) platform showOpcodes writer =
157163
if not mthinfo.IsGenericMethodDefinition && not mthinfo.DeclaringType.IsGenericTypeDefinition then
158-
disassembleConcreteMethod runtime mthinfo platform writer
164+
disassembleConcreteMethod runtime mthinfo platform showOpcodes writer
159165
else
160166
outputGenericMethod runtime mthinfo writer
161167

@@ -167,7 +173,7 @@ let withRuntime f =
167173

168174

169175
// disassemble assembly as jitted x86/x64 to text writer
170-
let disassemble asmPath (writer: TextWriter) platform =
176+
let disassemble asmPath (writer: TextWriter) platform showOpcodes =
171177

172178
// attach to self
173179
withRuntime (fun runtime ->
@@ -188,13 +194,13 @@ let disassemble asmPath (writer: TextWriter) platform =
188194

189195
for mth in getAllMethods ty do
190196
if mth.DeclaringType <> typeof<obj> then
191-
disassembleMethod runtime mth platform writer
197+
disassembleMethod runtime mth platform showOpcodes writer
192198

193199

194200
for sty in ty.GetNestedTypes() do
195201
for mth in getAllMethods sty do
196202
if mth.DeclaringType <> typeof<obj> then
197-
disassembleMethod runtime mth platform writer
203+
disassembleMethod runtime mth platform showOpcodes writer
198204
)
199205

200206
/// disassemble assembly as IL to text writer
@@ -205,19 +211,19 @@ let ildasm asmPath writer =
205211
disass.WriteModuleContents(pe)
206212

207213
/// disassemble assembly to writer
208-
let decompile asmPath writer language platform =
214+
let decompile asmPath writer language platform showOpcodes =
209215
match language with
210-
| Asm -> disassemble asmPath writer platform
216+
| Asm -> disassemble asmPath writer platform showOpcodes
211217
| IL -> ildasm asmPath writer
212218

213219
/// disassemble assembly to file
214-
let decompileToFile asmPath outPath language platform =
220+
let decompileToFile asmPath outPath language platform showOpcodes =
215221
use w = File.CreateText(outPath)
216-
decompile asmPath w language platform
222+
decompile asmPath w language platform showOpcodes
217223

218224

219225
/// disassemble assembly to console
220-
let decompileToConsole asmPath language platform =
226+
let decompileToConsole asmPath language platform showOpcodes =
221227
use s = Console.OpenStandardOutput()
222228
use w = new IO.StreamWriter(s)
223-
decompile asmPath w language platform
229+
decompile asmPath w language platform showOpcodes

src/fasmi/Program.fs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type Cmd =
99
| [<Mandatory; MainCommand; AltCommandLine("-s")>]Source of string
1010
| [<AltCommandLine("-c")>] Console
1111
| [<AltCommandLine("-o")>] Output of string
12+
| [<AltCommandLine("-x")>] Hex
1213
| [<AltCommandLine("-w")>] Watch
1314
| [<AltCommandLine("-p")>] Platform of Disassembly.Platform
1415
| [<AltCommandLine("-l")>] Language of Disassembly.Language
@@ -20,6 +21,7 @@ type Cmd =
2021
| Source _ -> "the source fsx or dotnet assembly file"
2122
| Console -> "output to console"
2223
| Output _ -> "specifiy the output file"
24+
| Hex _ -> "show instruction opcodes"
2325
| Watch -> "run in watch mode"
2426
| Platform _ -> "specify the platform for disassembly"
2527
| Language _ -> "specify the output language (asm/il)"
@@ -146,13 +148,14 @@ let main argv =
146148

147149

148150
logf "Disassembly"
149-
151+
152+
let showOpcodes = cmd.Contains Hex
150153

151154
// disassemble
152155
if cmd.Contains Console then
153-
Disassembly.decompileToConsole asmPath language platform
156+
Disassembly.decompileToConsole asmPath language platform showOpcodes
154157
else
155-
Disassembly.decompileToFile asmPath out language platform
158+
Disassembly.decompileToFile asmPath out language platform showOpcodes
156159

157160
if cmd.Contains Watch then
158161
// run in watch mode

tests/fasmi.tests/Tests.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ let disassembleFromSourceProject methodName =
3232

3333
Disassembly.withRuntime (fun runtime ->
3434
use writer = new IO.StringWriter()
35-
Disassembly.disassembleMethod runtime mth Disassembly.Platform.X64 writer
35+
Disassembly.disassembleMethod runtime mth Disassembly.Platform.X64 false writer
3636
writer.Flush()
3737
writer.ToString())
3838

0 commit comments

Comments
 (0)