<- previous    index    next ->

Lecture 5 Using debugger, options

See www.csee.umbc.edu/help/nasm/nasm_64.shtml for notes on using debugger.

A program that prints where its sections are allocated
(in virtual memory) is where_64.asm
My output, yours should be different, is

where_64.lst
where_64.out
where_64.dbg

; where_64.asm   print addresses of sections
; Assemble:	nasm -g -f elf64 -l where_64.lst  where_64.asm
; Link:		gcc -g3 -m64 -o where_64  where_64.o
; Run:		./where_64 > where_64.out
; Output:	you need to run it, results on my computer:
; data    a: at ???  waries with computer and software
; bss     b: at ???
; rodata  c: at ???
; code main: at ???
;
; to debug, typically after  segfault
; gdb where_64
; run
; backtrace
;           optionally: disassemble     x/60x main
;           end with    q               y

        extern	printf		; the C function, to be called
        section .data		; Data section, initialized variables
a:	db	0,1,2,3,4,5,6,7
fmt:    db "data    a: at %lX",10
	db "bss     b: at %lX",10
	db "rodata  c: at %lX",10
	db "code main: at %lX",10,0 

	section .bss		; reserved storage, uninitialized
b:	resq	8

	section	.rodata		; read only initialized storage
c:	db	7,6,5,4,3,2,1,0
	
        section .text           ; Code section.
        global main		; the standard gcc entry point
main:				; the program label for the entry point
	push	rbp
	mov	rbp,rsp
	push	rbx		; save callers registers
	
	mov	rdi,fmt		; pass address of fmt to printf
	lea	rsi,[a]		; using load effective address
	lea	rdx,[b]		; using load effective address
	lea	rcx,[c]		; using load effective address
	lea	r8,[main]	; using load effective address
	mov	rax,0		; no float
        call    printf		; Call C function

	mov	rdi,fmt		; pass address of fmt to printf
	mov	rsi,a		; just loading address
	mov	rdx,b		; just loading address
	mov	rcx,c		; just loading address
	mov	r8,main		; just loading address
	mov	rax,0		; no float
        call    printf		; Call C function

	pop	rbx		; restore callers registers
	mov	rsp,rbp
	pop	rbp
	mov	rax,0		; normal, no error, return value
	ret			; return

My output on gl.linux.umbc.edu is  where_64.out (my notes added)

data    a: at 6008CC            .data start
bss     b: at 600930            .bss start after .data
rodata  c: at 400658            .rodata start after .text
code main: at 4004D0            .text start
data    a: at 6008CC
bss     b: at 600930
rodata  c: at 400658
code main: at 4004D0



To run debugger and look at disassemble and memory dump
gdb where_64 > where_64.dbg
break main
run
disassemble
x/60x main
q
y

A small part of my output from debugger  where_64.dbg

GNU gdb (GDB) Red Hat Enterprise Linux (7.2-83.el6)
...
(gdb) break main
Breakpoint 1 at 0x4004d4: file where_64.asm, line 37.
(gdb) run
Starting program: /afs/umbc.edu/users/s/q/squire/home/cs313/where_64 

Breakpoint 1, main () at where_64.asm:37
37		push	rbx		; save callers registers
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.166.el6_7.3.x86_64
(gdb) disassemble
Dump of assembler code for function main:
   0x00000000004004d0 +0:	push   %rbp
   0x00000000004004d1 +1:	mov    %rsp,%rbp
=> 0x00000000004004d4 +4:	push   %rbx
   0x00000000004004d5 +5:	movabs $0x6008d4,%rdi
   0x00000000004004df +15:	lea    0x6008cc,%rsi
   0x00000000004004e7 +23:	lea    0x600930,%rdx
   0x00000000004004ef +31:	lea    0x400658,%rcx
   0x00000000004004f7 +39:	lea    0x4004d0,%r8
   0x00000000004004ff +47:	movabs $0x0,%rax
   0x0000000000400509 +57:	callq  0x4003b8  printf@plt
   0x000000000040050e +62:	movabs $0x6008d4,%rdi
   0x0000000000400518 +72:	movabs $0x6008cc,%rsi
   0x0000000000400522 +82:	movabs $0x600930,%rdx
   0x000000000040052c +92:	movabs $0x400658,%rcx
   0x0000000000400536 +102:	movabs $0x4004d0,%r8
   0x0000000000400540 +112:	movabs $0x0,%rax
   0x000000000040054a +122:	callq  0x4003b8  printf@plt
   0x000000000040054f +127:	pop    %rbx
   0x0000000000400550 +128:	mov    %rbp,%rsp
   0x0000000000400553 +131:	pop    %rbp
   0x0000000000400554 +132:	movabs $0x0,%rax
   0x000000000040055e +142:	retq   
   0x000000000040055f +143:	nop
End of assembler dump.
(gdb) x/60x main
0x4004d0 main:	0xe5894855	0xd4bf4853	0x00006008	0x48000000
...
A debugging session is active.
	Inferior 1 [process 23721] will be killed.
Quit anyway? (y or n) 


Options that may allow you to debug

Typical assembly language programming, may just use registers, or may keep most variables just in registers. Storing variables in memory may be needed for debugging. This example starts with a small C program,fib.c then codes efficient assembly language,fib_64l.asm Output, shows overflow fib_64l.out then keeps variables in memory,fib_64m.asm // fib.c same as computation as fib_64.asm #include <stdio.h> int main(int argc, char *argv[]) { long int c = 95; // loop counter long int a = 1; // current number, becomes next long int b = 2; // next number, becomes sum a+b long int d; // temp printf("fibinachi numbers\n"); for(c=c; c!=0; c--) { printf("%21ld\n",a); d = a; a = b; b = d+b; } }

implement fib.c using registers

; fib_64l.asm using 64 bit registers to implement fib.c global main extern printf section .data format: db '%15ld', 10, 0 title: db 'fibinachi numbers', 10, 0 section .text main: push rbp ; set up stack mov rdi, title ; arg 1 is a pointer mov rax, 0 ; no vector registers in use call printf mov rcx, 95 ; rcx will countdown from 95 to 0 mov rax, 1 ; rax will hold the current number mov rbx, 2 ; rbx will hold the next number print: ; We need to call printf, but we are using rax, rbx, and rcx. ; printf may destroy rax and rcx so we will save these before ; the call and restore them afterwards. push rax ; 32-bit stack operands are not encodable push rcx ; in 64-bit mode, so we use the "r" names mov rdi, format ; arg 1 is a pointer mov rsi, rax ; arg 2 is the current number mov rax, 0 ; no vector registers in use call printf pop rcx pop rax mov rdx, rax ; save the current number mov rax, rbx ; next number is now current add rbx, rdx ; get the new next number dec rcx ; count down jnz print ; if not done counting, do some more pop rbp ; restore stack mov rax, 0 ; normal exit ret

implement fib.c using memory

; fib_64m.asm using 64 bit memory more like C code ; // fib.c same as computation as fib_64m.asm ; #include <stdio.h> ; int main(int argc, char *argv[]) ; { ; long int c = 95; // loop counter ; long int a = 1; // current number, becomes next ; long int b = 2; // next number, becomes sum a+b ; long int d; // temp ; printf("fibinachi numbers\n"); ; for(c=c; c!=0; c--) ; { ; printf("%21ld\n",a); ; d = a; ; a = b; ; b = d+b; ; } ; } global main extern printf section .bss d: resq 1 ; temp unused, kept in register rdx section .data c: dq 95 ; loop counter a: dq 1 ; current number, becomes next b: dq 2 ; next number, becomes sum a+b format: db '%15ld', 10, 0 title: db 'fibinachi numbers', 10, 0 section .text main: push rbp ; set up stack mov rdi, title ; arg 1 is a pointer mov rax, 0 ; no vector registers in use call printf print: ; We need to call printf, but we are using rax, rbx, and rcx. mov rdi, format ; arg 1 is a pointer mov rsi,[a] ; arg 2 is the current number mov rax, 0 ; no vector registers in use call printf mov rdx,[a] ; save the current number, in register mov rbx,[b] ; mov [a],rbx ; next number is now current, in ram add rbx, rdx ; get the new next number mov [b],rbx ; store in ram mov rcx,[c] ; get loop count dec rcx ; count down mov [c],rcx ; save in ram jnz print ; if not done counting, do some more pop rbp ; restore stack mov rax, 0 ; normal exit ret ; return to operating system fib_64.out fibinachi numbers 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

Homework 3 is assigned

    <- previous    index    next ->

Other links

Go to top