123 lines
2.9 KiB
NASM
123 lines
2.9 KiB
NASM
; Fibonacci number generator using AMD64 assembly with Windows syscalls
|
|
; Uses lookup table for O(1) access
|
|
; Author: Assistant
|
|
|
|
global _main
|
|
extern _ExitProcess@4
|
|
extern _GetStdHandle@4
|
|
extern _WriteConsoleA@16
|
|
|
|
section .data
|
|
; Precomputed Fibonacci numbers (first 50)
|
|
fib_table dd 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
|
|
fib_table dd 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765
|
|
fib_table dd 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040
|
|
fib_table dd 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986, 102334155
|
|
fib_table dd 165580141, 267914296, 433494437, 701408733, 1134903170, 1836311903
|
|
|
|
; Console handles
|
|
hStdOut dd 0
|
|
|
|
; Error messages
|
|
msg_error db 'Error: Index out of range', 0
|
|
msg_success db 'Fibonacci number: ', 0
|
|
|
|
section .text
|
|
; Function to get Fibonacci number at index n (0-based)
|
|
; Input: RDI = index
|
|
; Output: RAX = Fibonacci number
|
|
get_fibonacci:
|
|
; Validate input
|
|
cmp rdi, 0
|
|
jl invalid_input
|
|
|
|
; Check if index is within range (max 50)
|
|
cmp rdi, 49
|
|
jg invalid_input
|
|
|
|
; Calculate address in table
|
|
mov rax, rdi
|
|
shl rax, 2 ; Multiply by 4 (DWORD size)
|
|
|
|
; Load Fibonacci number from table
|
|
mov eax, [fib_table + rax]
|
|
ret
|
|
|
|
invalid_input:
|
|
xor rax, rax ; Return 0 for invalid input
|
|
ret
|
|
|
|
; Function to print a number to console
|
|
print_number:
|
|
; Input: RAX = number to print
|
|
push rax
|
|
push rbx
|
|
push rcx
|
|
push rdx
|
|
|
|
; Convert number to string and print
|
|
mov rbx, 10
|
|
mov rcx, 0 ; Digit count
|
|
|
|
; Special case for zero
|
|
cmp rax, 0
|
|
jne convert_loop
|
|
mov rcx, 1
|
|
jmp print_digits
|
|
|
|
convert_loop:
|
|
cmp rax, 0
|
|
je print_digits
|
|
|
|
xor rdx, rdx ; Clear high bits
|
|
div rbx ; Divide by 10
|
|
push rdx ; Push remainder (digit)
|
|
inc rcx ; Increment digit count
|
|
jmp convert_loop
|
|
|
|
print_digits:
|
|
cmp rcx, 0
|
|
je done_printing
|
|
|
|
pop rax ; Get digit back
|
|
add rax, '0' ; Convert to ASCII
|
|
push rax
|
|
|
|
; Write character to console
|
|
mov edx, esp
|
|
push 1 ; Number of characters
|
|
push edx ; Address of character
|
|
push dword [hStdOut] ; Handle
|
|
call _WriteConsoleA@16
|
|
|
|
add rsp, 12 ; Clean up stack
|
|
|
|
dec rcx
|
|
jmp print_digits
|
|
|
|
done_printing:
|
|
pop rdx
|
|
pop rcx
|
|
pop rbx
|
|
pop rax
|
|
ret
|
|
|
|
; Main program entry point
|
|
_main:
|
|
; Get console handle
|
|
mov rdi, -11 ; STD_OUTPUT_HANDLE
|
|
call _GetStdHandle@4
|
|
mov [hStdOut], eax
|
|
|
|
; Test Fibonacci numbers
|
|
mov rdi, 10 ; Get 11th Fibonacci number (0-indexed)
|
|
call get_fibonacci
|
|
|
|
; Print result
|
|
push rax
|
|
call print_number
|
|
add rsp, 8
|
|
|
|
; Exit program
|
|
mov rdi, 0
|
|
call _ExitProcess@4 |