使用VS代码调试NASM

时间:2020-07-31 09:01:08

标签: c++ debugging assembly visual-studio-code nasm

我有一个简单的C ++程序,该程序调用了一些NASM代码:

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

我可以使用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)

我得到正确的结果。但是,我希望能够像C ++代码一样调试汇编代码。我可以在foo函数上创建一个断点(虽然不使用GUI),但是在暂停时它不会显示相应的源位置。有没有办法解决这个问题?我希望能够观看寄存器等。不确定VS代码中是否可能。

1 个答案:

答案 0 :(得分:5)

简短答案:否。在linux上,从vs-code启动gdb以调试asm代码导致快速崩溃。它甚至不允许您在asm代码上放置断点。

阅读更长的答案,以备不时之需。


我假设您没有使用Linux,因为我无法使用您提供的cmake在Linux上构建项目。我必须添加以下内容:

...
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()
...

好,所以现在该项目已构建并正在运行。但是,坏消息是我无法使用VS-Code设置“调试”环境。 VS-Code最初并没有很好的汇编支持,因此我对此并不感到惊讶。我尝试多次配置launch.json,但是每次启动GDB时,VS代码都会崩溃。在Windows或Mac上可能会或可能不会发生这种情况,因此我无法针对这些平台进行回答,但我认为它在那里无法正常工作。

我个人直接在终端上直接使用gdb,因为一旦您发现它就更强大且更易于使用。我将为您提供两个工作流程,您可以使用它们代替Vs代码。

使用终端

  • 构建可执行文件
  • 接下来使用gdb如下启动它:
gdb ./assembly-64 --tui

这将打开gdb,并带您进入推屏。

  • 让我们假设对于这种类型,我们想在foo处设置一个断点:
b foo
  • 现在我们的断点都已设置。我们准备开始调试会话。类型:
run
  • 它将在foo处断开。

但是请稍等,没有寄存器,我们应该如何查看它们?这是我最喜欢的gdb部分。类型:

layout regs

您将在顶部获得一个漂亮的外观窗口,向您显示所有寄存器。甚至会在寄存器更改时突出显示它们,从而使您可以轻松监视更改。

  • 除此之外,请使用n进行下一步,使用si进行修订。基本来说就差不多了。如果要在某个存储器位置或寄存器中查看该值。类型:
print $rax

还有很多其他功能,但这将使您快速入门。

GUI

当我发现QtCreator可以很好地调试asm + cpp文件时,我感到非常惊讶。只需加载您的cmake项目并放置断点即可。您可以从Menu->Window->Views->Registers启用寄存器窗格。截图:

enter image description here

还有其他GUI(用于gdb),nemiver,ddd等。