<- previous index next ->
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
<- previous index next ->