Hello, I'm a student who is learning assembly and using NASM for a project. I hope someone can help me, I am having difficulty compiling the program below.
I run the command 'nasm -felf64 physseed64.asm -o physseed64.o' and get an error which reads:
physseed64.asm:82: error: symbol 'par2d' undefined
physseed64.asm:85: error: symbol 'par3d' undefined
...
I know very little about NASM and have limited programming experience altogether, any help is appreciated
I'm using windows 10 64 bit, maybe that has something to do with it
This is the program:
;************************* physseed64.asm **********************************
default rel
%define NUM_TRIES 20 ; max number of tries for rdseed and rdrand instructions
%define TESTING 0 ; 1 for test only
global PhysicalSeed
; Direct entries to CPU-specific versions
global PhysicalSeedNone
global PhysicalSeedRDTSC
global PhysicalSeedVIA
global PhysicalSeedRDRand
global PhysicalSeedRDSeed
; ***************************************************************************
; Define registers used for function parameters, used in 64-bit mode only
; ***************************************************************************
%IFDEF WINDOWS
%define par1 rcx
%define par2 rdx
%define par3 r8
%define par1d ecx
%define par2d edx
%define par3d r8d
%ENDIF
%IFDEF UNIX
%define par1 rdi
%define par2 rsi
%define par3 rdx
%define par1d edi
%define par2d esi
%define par3d edx
%ENDIF
SECTION .text align=16
%IFDEF WINDOWS
global PhysicalSeedD@8 ; DLL version
PhysicalSeedD@8:
%ENDIF
PhysicalSeed:
jmp [PhysicalSeedDispatch] ; Go to appropriate version, depending on instructions available
PhysicalSeedRDSeed:
push rbx
test par2d, par2d ; NumSeeds
jz S300
js S900
mov par3d, par2d ; NumSeeds
shr par3d, 1
jz S150
; do 64 bits at a time
S100: mov ebx, NUM_TRIES
S110: rdseed rax
;db 48h, 0Fh, 0C7h, 0F8h ; rdseed rax
jc S120
; failed. try again
dec ebx
jz S900
jmp S110
S120: mov [par1], rax
add par1, 8
dec par3d
jnz S100 ; loop 64 bits
S150:
and par2d, 1
jz S300
; an odd 32 bit remains
S200: mov ebx, NUM_TRIES
S210: rdseed rax
;db 0Fh, 0C7h, 0F8h ; rdseed eax
jc S220
; failed. try again
dec ebx
jz S900
jmp S210
S220: mov [par1], eax
S300: mov eax, 4 ; return value
pop rbx
ret
S900: ; failure
xor eax, eax ; return 0
pop rbx
ret
PhysicalSeedRDRand:
push rbx
test par2d, par2d ; NumSeeds
jz R300
js R900
mov par3d, par2d ; NumSeeds
shr par3d, 1 ; NumSeeds/2
jz R150
; do 64 bits at a time
R100: mov ebx, NUM_TRIES
R110: rdrand rax
;db 48h, 0Fh, 0C7h, 0F0h ; rdrand rax
jc R120
; failed. try again
dec ebx
jz R900
jmp R110
R120: mov [par1], rax
add par1, 8
dec par3d
jnz R100 ; loop 64 bits
R150:
and par2d, 1
jz R300
; an odd 32 bit remains
R200: mov ebx, NUM_TRIES
R210: rdrand eax
;db 0Fh, 0C7h, 0F0h ; rdrand eax
jc R220
; failed. try again
dec ebx
jz R900
jmp R210
R220: mov [par1], eax
R300: mov eax, 4 ; return value
pop rbx
ret
R900: ; failure
xor eax, eax ; return 0
pop rbx
ret
PhysicalSeedVIA:
; VIA XSTORE supported
push rbx
%IFDEF WINDOWS
push rsi
push rdi
mov rdi, rcx ; seeds
mov esi, edx ; NumSeeds
%ENDIF
mov ecx, esi ; NumSeeds
and ecx, -2 ; round down to nearest even
jz T200 ; NumSeeds <= 1
; make an even number of random dwords
shl ecx, 2 ; number of bytes (divisible by 8)
mov edx, 3 ; quality factor
%if TESTING
mov eax, 1
rep stosb
%ELSE
db 0F3H, 00FH, 0A7H, 0C0H ; rep xstore instuction
%ENDIF
T200:
test esi, 1
jz T300
; NumSeeds is odd. Make 8 bytes in temporary buffer and store 4 of the bytes
mov rbx, rdi ; current output pointer
mov ecx, 4 ; Will generate 4 or 8 bytes, depending on CPU
mov edx, 3 ; quality factor
push rcx ; make temporary space on stack
mov rdi, rsp ; point to buffer on stack
%if TESTING
mov eax, 1
rep stosb
%ELSE
db 0F3H, 00FH, 0A7H, 0C0H ; rep xstore instuction
%ENDIF
pop rax
mov [rbx], eax ; store the last 4 bytes
T300:
mov eax, 2 ; return value
%IFDEF WINDOWS
pop rdi
pop rsi
%ENDIF
pop rbx
ret
PhysicalSeedRDTSC:
%IFDEF WINDOWS
push rbx
push rcx
push rdx
xor eax, eax
cpuid ; serialize
rdtsc ; get time stamp counter
pop rbx ; numseeds
pop rcx ; seeds
test ebx, ebx
jz U300 ; zero seeds
js U900 ; failure
mov [rcx], eax ; store time stamp counter as seeds[0]
add rcx, 4
dec ebx
jz U300
mov [rcx], edx ; store upper part of time stamp counter as seeds[1]
add rcx, 4
dec ebx
jz U300
xor eax, eax
U100: mov [rcx], eax ; store 0 for the rest
add rcx, 4
dec ebx
jnz U100
U300: mov eax, 1 ; return value
pop rbx
ret
U900: ; failure
xor eax, eax ; return 0
pop rbx
ret
%ELSE ; UNIX
push rbx
xor eax, eax
cpuid ; serialize
rdtsc ; get time stamp counter
test esi, esi ; numseeds
jz U300 ; zero seeds
js U900 ; failure
mov [rdi], eax ; store time stamp counter as seeds[0]
add rdi, 4
dec esi
jz U300
mov [rdi], edx ; store upper part of time stamp counter as seeds[1]
add rdi, 4
dec esi
jz U300
xor eax, eax
U100: mov [rdi], eax ; store 0 for the rest
add rdi, 4
dec esi
jnz U100
U300: mov eax, 1 ; return value
pop rbx
ret
U900: ; failure
xor eax, eax ; return 0
pop rbx
ret
%ENDIF
PhysicalSeedNone: ; no possible generation
xor eax, eax
test par2d, par2d ; numseeds
jz N200
N100: mov [par1], eax
add par1, 4
dec par2d
jnz N100
N200: ret ; return 0
PhysicalSeedDispatcher:
push rbx
%IFDEF WINDOWS
push rcx
push rdx
%ENDIF
; test if RDSEED supported
xor eax, eax
cpuid
cmp eax, 7
jb P200 ; RDSEED not supported
mov eax, 7
xor ecx, ecx
cpuid
bt ebx, 18
jc USE_RDSEED
P200: ; test if RDRAND supported
mov eax, 1
cpuid
bt ecx, 30
jc USE_RDRAND
; test if VIA xstore instruction supported
mov eax, 0C0000000H
push rax
cpuid
pop rbx
cmp eax, ebx
jna P300 ; not a VIA processor
lea eax, [rbx+1]
cpuid
bt edx, 3
jc VIA_METHOD
P300: ; test if RDTSC supported
mov eax, 1
cpuid
bt edx, 4
jc USE_RDTSC ; XSTORE instruction not supported or not enabled
FAILURE: ; No useful instruction supported
lea rax, [PhysicalSeedNone]
jmp P800
USE_RDRAND: ; Use RDRAND instruction
lea rax, [PhysicalSeedRDRand]
jmp P800
USE_RDSEED: ; Use RDSEED instruction (not tested yet)
lea rax, [PhysicalSeedRDSeed]
jmp P800
VIA_METHOD: ; Use VIA xstore instructions
lea rax, [PhysicalSeedVIA]
jmp P800
USE_RDTSC:
lea rax, [PhysicalSeedRDTSC]
;jmp P800
P800: mov [PhysicalSeedDispatch], rax
%IFDEF WINDOWS
pop rdx
pop rcx
%ENDIF
pop rbx
jmp rax ; continue in dispatched version
; -----------------------------------------------------------------
; Data section for dispatcher
; -----------------------------------------------------------------
SECTION .data
; Pointer to appropriate versions. Initially point to dispatcher
PhysicalSeedDispatch DQ PhysicalSeedDispatcher
%IFDEF POSITIONINDEPENDENT
; Fix potential problem in Mac linker
DD 0, 0
%ENDIF