GCC tells the last label under which the error occurs. But it doesnt give line number nor stack trace.
Introducing Jav debug
I have a similar utility in cpp called rep() which via variadic template takes a maximum of 10 arguments. NASM macros doesn't support variadic macros; but it supports overloaded macros based on number of paramters.
asm_io.inc
Paul A. Carter
PC Assembly Language
December 12, 2002
I added the debug macro
extern read_int, print_int, print_string, print_line
extern read_char, print_char, print_nl
extern sub_dump_regs, sub_dump_mem, sub_dump_math, sub_dump_stack
extern _printf
%macro dump_regs 1
push dword %1
call sub_dump_regs
%endmacro
;
; usage: dump_mem label, start-address, # paragraphs
%macro dump_mem 3
push dword %1
push dword %2
push dword %3
call sub_dump_mem
%endmacro
%macro dump_math 1
push dword %1
call sub_dump_math
%endmacro
%macro dump_stack 3
push dword %3
push dword %2
push dword %1
call sub_dump_stack
%endmacro
; private macro
; number of stack used by implementation
%define __jav_len__ 5
; private macro
; saves all registers so that you get that back how you left them
%macro __jav_save_registers__ 0
mov [esp-4*1], edx
mov [esp-4*2], ecx
mov [esp-4*3], eax
mov [esp-4*4], ebx
lahf ; modifies eax
mov [esp-4*5], eax
mov eax, [esp-4*3] ; restore the value of eax
%endmacro
; private macro
; restores the registers to the values you left them in
%macro __jav_restore_registers__ 0
pop eax
sahf
pop ebx
pop eax
pop ecx
pop edx
%endmacro
; private macro
; gets a scalar value
%macro __jav_get__ 1
mov ebx, dword %1
%endmacro
; private macro
; dereference and gets the scalar
%macro __jav_get__ 2
mov ebx, %1
mov ebx, [ebx+%2]
%endmacro
; private macro
; used to copy dword
; return value stored in ebx
%macro __jav_copy32__ 2+
__jav_get__ %2
mov %1, ebx
mov ebx, [esp-4*4] ; restore the value of ebx
%endmacro
; public macro
; pass this as argument to debug macro
; dereferences obj and return scalar at index offset
%define jav_member(obj,index) { obj, index }
; param 1: string format to print
%macro debug 1
section .data
%%msg db %1, 10, 0
section .text
__jav_save_registers__
__jav_copy32__ [esp-4*(__jav_len__+1)], %%msg
sub esp, 4*(__jav_len__+1)
call _printf
add esp, 4*1
__jav_restore_registers__
%endmacro
; param 1: string format to print
; param 2: arguments to string format
%macro debug 2
section .data
%%msg db %1, 10, 0
section .text
__jav_save_registers__
__jav_copy32__ [esp-4*(__jav_len__+1)], %2
__jav_copy32__ [esp-4*(__jav_len__+2)], %%msg
sub esp, 4*(__jav_len__+2)
call _printf
add esp, 4*2
__jav_restore_registers__
%endmacro
%macro debug 3
section .data
%%msg db %1, 10, 0
section .text
__jav_save_registers__
__jav_copy32__ [esp-4*(__jav_len__+1)], %3
__jav_copy32__ [esp-4*(__jav_len__+2)], %2
__jav_copy32__ [esp-4*(__jav_len__+3)], %%msg
sub esp, 4*(__jav_len__+3)
call _printf
add esp, 4*3
__jav_restore_registers__
%endmacro
%macro debug 4
section .data
%%msg db %1, 10, 0
section .text
__jav_save_registers__
__jav_copy32__ [esp-4*(__jav_len__+1)], %4
__jav_copy32__ [esp-4*(__jav_len__+2)], %3
__jav_copy32__ [esp-4*(__jav_len__+3)], %2
__jav_copy32__ [esp-4*(__jav_len__+4)], %%msg
sub esp, 4*(__jav_len__+4)
call _printf
add esp, 4*4
__jav_restore_registers__
%endmacro
%macro debug 5
section .data
%%msg db %1, 10, 0
section .text
__jav_save_registers__
__jav_copy32__ [esp-4*(__jav_len__+1)], %5
__jav_copy32__ [esp-4*(__jav_len__+2)], %4
__jav_copy32__ [esp-4*(__jav_len__+3)], %3
__jav_copy32__ [esp-4*(__jav_len__+4)], %2
__jav_copy32__ [esp-4*(__jav_len__+5)], %%msg
sub esp, 4*(__jav_len__+5)
call _printf
add esp, 4*5
__jav_restore_registers__
%endmacro
%macro debug 6
section .data
%%msg db %1, 10, 0
section .text
__jav_save_registers__
__jav_copy32__ [esp-4*(__jav_len__+1)], %6
__jav_copy32__ [esp-4*(__jav_len__+2)], %5
__jav_copy32__ [esp-4*(__jav_len__+3)], %4
__jav_copy32__ [esp-4*(__jav_len__+4)], %3
__jav_copy32__ [esp-4*(__jav_len__+5)], %2
__jav_copy32__ [esp-4*(__jav_len__+6)], %%msg
sub esp, 4*(__jav_len__+6)
call _printf
add esp, 4*6
__jav_restore_registers__
%endmacro
%macro debug 7
section .data
%%msg db %1, 10, 0
section .text
__jav_save_registers__
__jav_copy32__ [esp-4*(__jav_len__+1)], %7
__jav_copy32__ [esp-4*(__jav_len__+2)], %6
__jav_copy32__ [esp-4*(__jav_len__+3)], %5
__jav_copy32__ [esp-4*(__jav_len__+4)], %4
__jav_copy32__ [esp-4*(__jav_len__+5)], %3
__jav_copy32__ [esp-4*(__jav_len__+6)], %2
__jav_copy32__ [esp-4*(__jav_len__+7)], %%msg
sub esp, 4*(__jav_len__+7)
call _printf
add esp, 4*7
__jav_restore_registers__
%endmacro
%macro debug 8
section .data
%%msg db %1, 10, 0
section .text
__jav_save_registers__
__jav_copy32__ [esp-4*(__jav_len__+1)], %8
__jav_copy32__ [esp-4*(__jav_len__+2)], %7
__jav_copy32__ [esp-4*(__jav_len__+3)], %6
__jav_copy32__ [esp-4*(__jav_len__+4)], %5
__jav_copy32__ [esp-4*(__jav_len__+5)], %4
__jav_copy32__ [esp-4*(__jav_len__+6)], %3
__jav_copy32__ [esp-4*(__jav_len__+7)], %2
__jav_copy32__ [esp-4*(__jav_len__+8)], %%msg
sub esp, 4*(__jav_len__+8)
call _printf
add esp, 4*8
__jav_restore_registers__
%endmacro
%macro debug 9
section .data
%%msg db %1, 10, 0
section .text
__jav_save_registers__
__jav_copy32__ [esp-4*(__jav_len__+1)], %9
__jav_copy32__ [esp-4*(__jav_len__+2)], %8
__jav_copy32__ [esp-4*(__jav_len__+3)], %7
__jav_copy32__ [esp-4*(__jav_len__+4)], %6
__jav_copy32__ [esp-4*(__jav_len__+5)], %5
__jav_copy32__ [esp-4*(__jav_len__+6)], %4
__jav_copy32__ [esp-4*(__jav_len__+7)], %3
__jav_copy32__ [esp-4*(__jav_len__+8)], %2
__jav_copy32__ [esp-4*(__jav_len__+9)], %%msg
sub esp, 4*(__jav_len__+9)
call _printf
add esp, 4*9
__jav_restore_registers__
%endmacro
%macro debug 10
section .data
%%msg db %1, 10, 0
section .text
__jav_save_registers__
__jav_copy32__ [esp-4*(__jav_len__+1)], %10
__jav_copy32__ [esp-4*(__jav_len__+2)], %9
__jav_copy32__ [esp-4*(__jav_len__+3)], %8
__jav_copy32__ [esp-4*(__jav_len__+4)], %7
__jav_copy32__ [esp-4*(__jav_len__+5)], %6
__jav_copy32__ [esp-4*(__jav_len__+6)], %5
__jav_copy32__ [esp-4*(__jav_len__+7)], %4
__jav_copy32__ [esp-4*(__jav_len__+8)], %3
__jav_copy32__ [esp-4*(__jav_len__+9)], %2
__jav_copy32__ [esp-4*(__jav_len__+10)], %%msg
sub esp, 4*(__jav_len__+10)
call _printf
add esp, 4*10
__jav_restore_registers__
%endmacro
gcc -S
on a.c
file, with and without-g
. e.g. have a look at the stuff after the.section .debug_info,"",@progbits
directive in godbolt.org/z/EdeTvA. (gcc compiling for Linux/ELF MIPS). What target are you compiling for, BTW? Different debug formats exist, with DWARF being the current widely-used on on Linux/ELF targets. – Torritorricelli-fverbose-asm
does (try adding it on the Godbolt link above), and assemble it with an assembler that generates debug info for asm source-level debugging. (likeas -g
). So you give yourself some way to single-step the asm and see some strings from your compiler attached to each instruction, naming the operands. Doesn't help so much for setting watchpoints, but can help follow the how the compiler is implementing the source logic. – Torritorricellimov rdx, QWORD PTR [rbp-8] # tmp89, a
. Do I understand correctly that compiler now knows thatrdx
istmp89
andQWORD PTR [rbp-8]
isa
just from that? Willgcc -g <my-asm>
compilation do it? If yes, this may be exactly what I need. – CondolenttmpXX
for internal temporaries. And yeah, I thinkgcc -g foo.s
will give you the debug info to help GDB show the right asm source lines. – Torritorricelli