I know that a newcomer and hobbycoder should probably not mess with asm statements.. but I want to =) I'm already sorry that I am mixing at&t and intel syntax in the code below.
gcc --version
gcc (x86_64-win32-seh-rev1, Built by MinGW-W64 project) 6.3.0
nim -v
Nim Compiler Version 1.2.4 [Windows: amd64]
Compiled at 2020-06-26
I would expect that this function below would be naked and just does a add and jmp call
proc test {.asmnoStackFrame.} =
asm """
add $0x1, %eax
jmp 0x004118ED
"""
but debugging this function shows:
push ebp
mov ebp, esp
add eax, 01
jmp 0x004118ED
Why does it modify the stack?
How to use nim identifiers? In visual cpp you can simply use variables in inline asm but:
const myaddr = 0x123456
asm """
jmp `myaddr`
"""
doesn't compiles at all. Im wondering how I could copy a register address into a nim identifier aswell.
I really would like to use intel syntax but code compiled with --passC:"-masm=intel" doesn't recognizes any nim identifiers. Is there simply no support for it?
I would expect that this function below would be naked and just does a add and jmp call
Unless you compile with optimizations on, all C function push the stack base pointer on the stack on function entry (ebp), then save the stack pointer (esp) in ebp then do the function. Compile with optimizations, in particular -fomit-stack-pointer if you want to avoid the extra save/restore.
Nim identifiers in asm
The ASM statement doesn't support string interpolation, you need to build the string via a macro or use GCC syntax
Macro
import macros, strutils
macro myASMStmt(myAddr: static int): untyped =
result = nnkAsmStmt.newTree(
newEmptyNode(),
newLit "jmp 0x" & toHex(myAddr)
)
echo result.toStrLit
const myaddr = 0x123456
proc foo() =
myASMStmt(myaddr)
GCC, use the immediate syntax
proc bar() =
asm """
jmp %[offset]
:
: [offset] "i" (`myaddr`)
:
"""
If you want concrete standalone example of Nim ASM:
Experiments on bigint addition:
A macro assembler to ease usage of assembly in Nim (living in a branch for now):
Concrete usages of the macro assembler (note like Intel syntax it's (dst, operands) order: