; test source file for assembling to ELF64 shared library ; build with: ; nasm -f elf64 elf64so.asm ; ld -shared -o elf64so.so elf64so.o ; test with: ; gcc -o elf64so elftest64.c ./elf64so.so ; ./elf64so ; This file should test the following: ; [1] Define and export a global text-section symbol ; [2] Define and export a global data-section symbol ; [3] Define and export a global BSS-section symbol ; [4] Define a non-global text-section symbol ; [5] Define a non-global data-section symbol ; [6] Define a non-global BSS-section symbol ; [7] Define a COMMON symbol ; [8] Define a NASM local label ; [9] Reference a NASM local label ; [10] Import an external symbol ; [11] Make a PC-relative call to an external symbol ; [12] Reference a text-section symbol in the text section ; [13] Reference a data-section symbol in the text section ; [14] Reference a BSS-section symbol in the text section ; [15] Reference a text-section symbol in the data section ; [16] Reference a data-section symbol in the data section ; [17] Reference a BSS-section symbol in the data section BITS 64 GLOBAL lrotate:function ; [1] GLOBAL greet_s:function ; [1] GLOBAL greet_m:function ; [1] GLOBAL asmstr:data asmstr.end-asmstr ; [2] GLOBAL textptr:data 8 ; [2] GLOBAL selfptr:data 8 ; [2] GLOBAL useless:data 8 ; [3] GLOBAL integer:data 8 ; [3] EXTERN printf ; [10] COMMON commvar 8:8 ; [7] EXTERN _GLOBAL_OFFSET_TABLE_ SECTION .text ; prototype: long lrotate(long x, int num); lrotate: ; [1] push rbp mov rbp,rsp mov rax,rdi mov rcx,rsi .label rol rax,1 ; [4] [8] loop .label ; [9] [12] mov rsp,rbp pop rbp ret ;; prototype: void greet_*(void); ;; ;; Arguments are: rdi - rsi - rdx - rcx - r8 - r9 ;; Registers: rbx, rbp, r12-r15 are saved ;; greet_s() is Small PIC model, greet_m() is Medium PIC model ;; (Large model cannot be linked with other code) ;; greet_s: ;; This instruction is useless, this is only a test... cmp qword [rel integer wrt ..got],0 mov rax,[rel commvar wrt ..got] ; &commvar mov rcx,[rax] ; commvar mov rax,[rel integer wrt ..got] ; &integer mov rsi,[rax] lea rdx,[rsi+1] mov [rel localint],rdx ; localint = integer+1 mov rax,[rel localptr] ; localptr mov rdx,[rax] ; *localptr = localint lea rdi,[rel printfstr] xor eax,eax ; No fp arguments jmp printf wrt ..plt ; [10] greet_m: push r15 ; Used by convention... lea r15,[rel _GLOBAL_OFFSET_TABLE_] mov rax,[rel commvar wrt ..got] ; &commvar mov rcx,[rax] ; commvar mov rax,[rel integer wrt ..got] ; &integer mov rsi,[rax] lea rdx,[rsi+1] mov rax,localint wrt ..gotoff ; &localint - r15 mov [rax+r15],rdx ; localint = integer+1 mov rax,localptr wrt ..gotoff ; &localptr - r15 mov rax,[rax+r15] ; localptr mov rdx,[rax] ; *localptr = localint mov rdi,printfstr wrt ..gotoff ; &printfstr - r15 add rdi,r15 ; &printfstr xor eax,eax ; No fp arguments pop r15 jmp printf wrt ..plt ; [10] SECTION .data ; a string asmstr db 'hello, world', 0 ; [2] .end: ; a string for Printf printfstr db "integer=%ld, localint=%ld, commvar=%ld", 10, 0 ; some pointers localptr dq localint ; [5] [17] textptr dq greet_s wrt ..sym ; [15] selfptr dq selfptr wrt ..sym ; [16] SECTION .bss ; a useless symbol useless resq 1 ; an integer integer resq 1 ; [3] ; a local integer localint resq 1 ; [6]