I have a simple C++ program that calls some NASM code:
main.cpp:
#include <iostream>
extern "C" int foo();
int main() {
std::cout << "The result is: " << foo() << std::endl;
return 0;
}
foo.asm:
bits 64
global foo
section .text
foo:
mov rax, 123
inc rax
ret
I can compile everything with CMake
cmake_minimum_required (VERSION 3.15)
project (assembly-x64 LANGUAGES CXX ASM_NASM)
# old school CMAKE to handle NASM formats
if(WIN32)
set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -F cv8")
set(CMAKE_ASM_NASM_OBJECT_FORMAT win64)
elseif(APPLE)
set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -F dwarf")
set(CMAKE_ASM_NASM_OBJECT_FORMAT macho64)
else()
set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -F dwarf")
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
endif()
add_executable(assembly-x64)
target_compile_features(assembly-x64 PUBLIC cxx_std_17)
target_sources(assembly-x64 PRIVATE main.cpp foo.asm)
and I get the correct result. However, I'd like to be able to debug the assembly code just like I would the C++ code. I can create a breakpoint on the foo
function (not using the GUI though), but it doesn't show me the corresponding source location when it pauses. Is there a way around that issue? I'd like to be able to watch registers, etc. Not sure if it's possible in VS code.
Short Answer: No. On linux, launching gdb from vs-code to debug asm code resulted in a quick crash. It doesn't even let you put breakpoints on asm code.
Read the longer answer in case you want to know about the alternatives.
I assume you are not using Linux, because I was unable to build the project on Linux with the cmake you provided. I had to add the following:
...
else()
set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -F dwarf")
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
# had to add this to build on linux
set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> <INCLUDES> \
<FLAGS> -f ${CMAKE_ASM_NASM_OBJECT_FORMAT} -o <OBJECT> <SOURCE>")
endif()
...
Ok, so now the project is built and running. However, the bad news is that I was unable to set up "debugging" environment with VS-Code. VS-Code doesn't really have good assembly support to begin with so I am not really surprised here. I tried to configure launch.json
multiple times, but everytime I launch GDB, VS-Code crashes. This may or may not happen on Windows or Mac, so I can not answer for those platforms but I assume it will not work there.
I personally just use gdb
from terminal directly because it is more powerful and easy to use once you figure it out. I will give you two work flows which you can use instead of Vs-code.
gdb ./assembly-64 --tui
This will open gdb
and bring you to the tui screen.
foo
, for this type:b foo
run
foo
.But wait a minute, there are no registers, how should we see them? This is my favourite part about gdb. Type:
layout regs
And you will get a beautiful look window at top showing you all the registers. It will even highlight the registers as they change making it easy for you to monitor changes.
n
to step next, use si
to step into. That's pretty much it for the basics. If you want to see the value at some memory location, or a register. Type:print $rax
There's a lot more to this, but this will give you a quick start.
I was pleasantly surprised when I discovered that QtCreator
can debug asm + cpp files very nicely. Just load up your cmake project and place your breakpoints. You can enable registers pane from Menu->Window->Views->Registers
. Screenshot:
There are other guis(for gdb) out there, nemiver, ddd etc.
To debug C++ code and assembly code simultaneously, you can do this with gobolt online: https://godbolt.org/
If you just want to write assembly and debug in vscode, let me tell you the method I just learned.
There is a great project for this. https://github.com/newtonsart/vscode-assembly
You should also do these additionally.
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
sudo apt install gcc-multilib
(https://stackoverflow.com/a/32855954/6646336) I used extra gcc argument for some errors.
# .vscode/tasks.json
# find gcc command and add <nostdlib> in two line
... gcc -nostdlib -m64...
... gcc -nostdlib -m32...
But still you can't set a breakpoint in (*.s, *.asm) file. vscode doesn't accept. You must enable in settings (keyword: debug.allowBreakpointsEverywhere = true
)
And final step: Set a breakpoint and select your debugging type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With