In LLDB, the step command steps over a whole asm{} block as a single "statement". Is there a way to make it treat each instruction separately so you don't have to use si to step instructions, and switch to disassembly mode to see your current position?
As a part of a course I am attending, we are writing inline asm in C. They are using Visual Studio on windows, to write and debug MSVS assembly. I wanted to get this up and running on my M2 Macbook (I can run a VM, but that is boring)
It was pretty easy to get the thing to compile. I use clang and copile like this:
clang -fasm-blocks -target x86_64-apple-macos main.c -g -O0
Here is an example code snippet:
#include <inttypes.h>
#include <stdio.h>
uint8_t count1(uint32_t x) {
uint8_t out;
__asm {
mov edx, x
mov al, 0
next: cmp edx, 0
je done
mov cl, dl
and cl, 1
add al, cl
shr edx, 1
jmp next
done:
mov out, al
}
return out;
}
int main() {
uint32_t x = 0x5789ABCD;
uint8_t cnt = count1(x);
printf("Number of 1s in 0x%X: %hhu\n", x, cnt);
}
The only thing that I have to do differently, is the return value. I have to move it to a C variable manually and return it. If you know how to make this work implicitly, it would be awesome, but that isn't a big deal for me.
The problem came with debugging. I use neovim and have nice debugging experience with nvim-dap and codelldb. However when I step through the code snipped above, the asm block runs in one step.
I have tried debugging with raw lldb on the cli and it does the same thing. I can step through the asm with si and di -F intel but that is a little cumbersome.
I suppose I am only missing a flag in the compilation step to generate debug symbols for the asm block. Does anyone know how to step through the __asm block within LLDB and consequently neovim? Is my understanding of the problem correct?
asm{}block. Butclang -fasm-blocksdefinitely does not respect that, probably not evenclang-clis compatible with such code. Clang treats it as undefined behaviour when a caller uses the return value of a function that doesn't return one (in C; in C++ it's UB even to fall off the end)asm{}blocks are necessarily inefficient, forcing inputs to be in memory not registers. MSVC itself lets you avoid bouncing one output (a return value) through memory with that hack you mention, clang doesn't. But if you care about efficiency, clang also supports GNU C inline asm, where you tell the compiler about your inputs and outputs with constraints, and can even let it pick registers that are convenient for the context where it's inlining your function. 'asm', '__asm' and '__asm__'? / stackoverflow.com/tags/inline-assembly/info__asmblock one-by-one#lineor.locdirectives? Alternately, what about this (from codelldb)? This is supposed to allow you to "perform instruction-level stepping rather than source-level stepping.".locdirectives into the asm and it will work! I attempted to make a Clang plugin that will do it automatically, but I hit a segfault onRewriter.getRangeSize(..)and I can't seem to figure out what's wrong... github.com/Hackder/asm_debug