<- 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.out

; where_64.asm   print addresses of sections
; Assemble:	nasm -g -f elf64 -l where_64.lst  where_64.asm
; Link:		gcc -m64 -o where_64  where_64.o
; Run:		./where_64 > where_64.out
; Output:	you need to run it, on my computer
; data    a: at 601034
; bss     b: at 60108C
; rodata  c: at 400640
; code main: at 400530
;
; to debug, typically after  segfault
; gdb where_64
; run
; backtrace
;             hopefully this will point to where the problem is in source

        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

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 52 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

Homework 3 is assigned

    <- previous    index    next ->

Other links

Go to top