Recent Posts

Pages: 1 ... 6 7 [8] 9 10
71
Example Code / Re: Fibonacci, with bigger numbers
« Last post by debs3759 on November 21, 2023, 09:58:04 PM »
Another way to find the nth number (an) in the sequence is

an = [Phi^n – (phi)^n] / Sqrt[5].
where Phi = (1 + Sqrt[5]) / 2
and phi = (1 – Sqrt[5]) / 2 (or (-1 / Phi))
72
Example Code / Fibonacci, with bigger numbers
« Last post by andyz74 on November 21, 2023, 08:19:28 PM »
This is a mess of a code, I have to admire, but it works, as I see.
In this version, it is hardcoded for a maximum until fib(399), which has 63 numbers (or ciphers? sorry, don't know it correct in english...)
and a hardcoded maximum until 80 numbers (or ciphers? sorry, don't know it correct in english...)

This is Linux 64bit.

Code: [Select]
; fibogr.asm
;
; errechnet Fibonacci's und gibt jene aus.
; nasm -f elf64 fibogr.asm
; ld -s -o fibogr fibogr.o      "warum -s ? -s "strippt" die Debug-Infos weg. Wenn man debuggen will, lieber ohne -s"

[bits 64]

SECTION .data

_overflow_msg db '*** Series overflown.',0ah
len_overflow_msg equ $-_overflow_msg
_one db '1 '
_endl db 10
_leerz db 32
ziffer db 0

SECTION .bss
 f1array  :  resb 80
 f2array  :  resb 80
 f3array  :  resb 80



global _start ; global entry point export for ld

SECTION .text

_start:
start:


mov rax, 0
.nochmal1:
mov byte [f1array+rax],0
mov byte [f2array+rax],0
mov byte [f3array+rax],0

inc rax
cmp rax, 81
jne .nochmal1
mov byte [f1array],1
mov byte [f2array],1

mov r15, 300 ; HARDCODED : 300 fib-Zahlen machen.
; soviele fib() sollen errechnet werden...
cmp eax, 0
jz .done

dec r15
jz .done ; wenn fertig, ganz runter, Ende



call .ausgabe_f2
call .crlf

.calc_fibo:
call .kill_f3

mov r14, 0 ; r14 ist Index, wo im Array wir sind.
mov cl, 0
.alle_ziffern:
mov rax, 0
mov rbx, 0
mov r13, 0
mov al, byte [f1array+r14]
add [f3array+r14], al
mov bl, byte [f2array+r14]
add [f3array+r14], bl
mov bl, byte [f3array+r14]
jo .overflow ; Ergebnis zu groß für Datentyp?
nop
nop

inc r14
cmp r14, 80
jne .alle_ziffern

; *****  hier fertig mit rechnen *******



call .adjust_f3

call .shift_arrays

call .ausgabe_f3
call .crlf



 .done:
; call .crlf

dec r15
jnz .calc_fibo ; alle Fibos berechnet ?

mov eax, 1 ; Programmende
mov ebx, 0
int 80h

.overflow:
mov eax, 4
mov ebx, 1
mov ecx, _overflow_msg
mov edx, len_overflow_msg
int 80h

mov eax, 1
mov ebx, 1
int 80h

; *******************************************************************
; *********************** ab hier proceduren ************************
; *******************************************************************


.shift_arrays:
push rax
push rbx
push rcx
push rdx
mov rax, 0
.nochmal3:
mov ch, byte [f2array+rax]
mov byte [f1array+rax], ch

mov ch, byte [f3array+rax]
mov byte [f2array+rax], ch
inc rax
cmp rax, 80
jne .nochmal3
pop rdx
pop rcx
pop rbx
pop rax
ret


.crlf:
push rax
push rbx
push rcx
push rdx
mov eax, 4 ; schreiben
mov ebx, 1
mov ecx, _endl
mov edx, 1
int 80h
pop rdx
pop rcx
pop rbx
pop rax
ret

.leer:
push rax
push rbx
push rcx
push rdx
mov eax, 4 ; schreiben
mov ebx, 1
mov ecx, _leerz
mov edx, 1
int 80h
pop rdx
pop rcx
pop rbx
pop rax
ret


.ausgabe_f1:
push rax
push rbx
push rcx
push rdx
mov r12, 80 ; Zur Ausgabe des Arrays r12 als Index
.noch_ein_array_teil:
dec r12
mov rcx, 0
mov cl, byte [f1array+r12]
add ecx, "0"
mov byte[ziffer], cl
mov eax, 4 ; fertige "Zahl" ausgeben
mov ebx, 1
mov edx, 1 ; Länge, hier bei uns immer 1
mov ecx, ziffer
int 80h
cmp r12, 0
jne .noch_ein_array_teil
pop rdx
pop rcx
pop rbx
pop rax
ret

.ausgabe_f2:
push rax
push rbx
push rcx
push rdx
mov r12, 80 ; Zur Ausgabe des Arrays r12 als Index
.noch_ein_array_teil2:
dec r12
mov rcx, 0
mov cl, byte [f2array+r12]
add ecx, "0"
mov byte[ziffer], cl
mov eax, 4 ; fertige "Zahl" ausgeben
mov ebx, 1
mov edx, 1 ; Länge, hier bei uns immer 1
mov ecx, ziffer
int 80h
cmp r12, 0
jne .noch_ein_array_teil2
pop rdx
pop rcx
pop rbx
pop rax
ret

.ausgabe_f3:
push rax
push rbx
push rcx
push rdx
mov r13, 0  ; solange führende Nullen, später dann 1
mov r12, 80 ; Zur Ausgabe des Arrays r12 als Index
.noch_ein_array_teil3:
dec r12
mov rcx, 0
mov cl, byte [f3array+r12]
cmp r13, 0
jne .write_it ; wenn schon richtige Ziffern waren, dann hüpfen

cmp cl, 0
jne .write_it_vor ; wenn ab jetzt richtige Zahlen kommen, dann hüpfen

mov byte[ziffer], 32 ; führende Null soll Leerzeichen werden
jmp .ausgabe_leerz
.write_it_vor:
mov r13,1
.write_it:
add cl, "0"
mov byte[ziffer], cl
.ausgabe_leerz:
mov eax, 4 ; fertige "Zahl" ausgeben
mov ebx, 1
mov edx, 1 ; Länge, hier bei uns immer 1
mov ecx, ziffer
int 80h
cmp r12, 0
jne .noch_ein_array_teil3
pop rdx
pop rcx
pop rbx
pop rax
ret

.kill_f3:
push rax
mov rax, 0
.nochmal2:
mov byte [f3array+rax],0
inc rax
cmp rax, 81
jne .nochmal2
pop rax
ret


.adjust_f3:
push rax
push rbx ; Indexzähler
push rcx ; einzelner Wert
push rdx
mov rcx, 0
.nochmal4:
mov bx, 0
mov bl, byte [f3array+rcx]
cmp bl, 10 ; größer als 9  ?
jl .good
xor ax, ax
mov ax, bx
add byte [f3array+rcx+1], 1
xor rdx, rdx
mov bx, 10
div bx
; Zehner in eax, Einer in rdx
mov byte [f3array+rcx], dl
.good:
inc rcx
cmp rcx, 79
jne .nochmal4
pop rdx
pop rcx
pop rbx
pop rax
ret

73
Programming with NASM / Re: Printing of floating point values
« Last post by andyz74 on November 14, 2023, 07:15:45 PM »
Many thanks, I corrected my code now, and it does, what I want. :-)
74
Programming with NASM / Re: Printing of floating point values
« Last post by fredericopissarra on November 10, 2023, 11:38:54 AM »
Does anyone see, what is my failure, please?
Yep... Will be 0...

Let's take a look at 12.34 in bynary:
Code: [Select]
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main( void )
{
  double d = 12.34;
  uint64_t *p = (uint64_t *)&d;

  printf( "%#" PRIx64 "\n", *p );
}
So, compiling, linking and running:
Code: [Select]
$ cc -O2 -o test test.c
$ ./test
0x4028ae147ae147ae
A floating point value is encoded as described here: https://en.wikipedia.org/wiki/Double-precision_floating-point_format
So, 100 (integer) is a double encoded as ~4.94066e-322 (almost 0). What you meant do to is:
Code: [Select]
; Input xmm0
; Ouput rax
fmult100_trunc:
  mulsd xmm0,[.m100]
  cvttsd2si rax,xmm0
  ret
.m100:
  dq  100.0         ; ".0" is necessary here.

PS: Try to avoid using "memory" variables since you have 16 integer registers and 16 xmm registers available.
PS2: This kind of code works only if the floating point value is in 'integer' range. But notice that a single precision floating point value has a range way larger than that. Take a look at this paper: https://legacy.cs.indiana.edu/~dyb/pubs/FP-Printing-PLDI96.pdf
75
Programming with NASM / Re: Printing of floating point values
« Last post by andyz74 on November 09, 2023, 04:58:44 PM »
OK, so I read a lot, and I try a lot, but unfortunately without much success.  I would be very pleased, if someone could help me further here.

I give a float variable "para_f" with the value 12.34

Then I get the integer part with

Code: [Select]
print_float:
cvttsd2si rdx, [para_f]     ;   rdx ist jetzt ganzzahlteil
ret

...and  with my own print-routine, I can print out the integer part 12.

Then I have a second part, where I try to multiply the "para_f" by 100 and afterwards print out, but I get a "0"

Code: [Select]
print_floatmul100:
movsd xmm0, [para_f] ; single-prec-float nach xmm0
mov dword [varq], 100            ; 100 nach varq und dann nach xmm1
movsd xmm1, [varq]
mulsd xmm0, xmm1   
movsd [varq], xmm0         ;
cvttsd2si rdx, [varq]
ret

I see in debugger, that xmm0 is at last point 4d2 hexadecimal, what is 1234 in decimal.  This is correct.
But then I get output zero, with my print-routine.

Does anyone see, what is my failure, please?
76
Example Code / Re: A little program to seek and write primes, with hardcoded maximum
« Last post by andyz74 on November 09, 2023, 01:37:37 PM »
This one does the same, but sets up an array for the primes, which can be used to divide thru. So, only the necessary divisions will be made, what saves time.

Code: [Select]
; 64-bit  ... gibt Primzahlen aus
; by myself
; nasm -f elf64 primzahlen05.asm
; ld -s -o primzahlen05 primzahlen05.o
; time :   0,303 sec (Optimierung : prüft nur von 1 bis Wurzel(zu überprüfende Zahl)
; nur noch durch primzahlen teilen, daher array einführen...
; Notiz : Wurzel ab 04 mit FPU, vllt besser...


[bits 64]

; here just variables ---------------------------------------

SECTION .data

para_b db 0
para_w dq 0
primzahl_boolean db 0
ziffer db 0
zahl dd 0
crlf db 13,10


section .bss
      res :  resq 1     ;reserve 1 quad word for result
 p_array  :  resq 18000
 p_index  :  resq 1
 
global _start ; global entry point export for ld

SECTION .text

_start:
jmp start2


zeige_tabelle: ; wenn Primzahl, dann im Array abspeichern ...
push rax ; ... wir machen naemlich eine Liste.
push rsi
mov rsi, 0
again:
inc rsi
mov rax, 0
call print_dez
mov rax, qword [p_array+rsi*8]
call print_dez
cmp rsi, qword [p_index]
jle again
call zeilensprung
pop rsi
pop rax
ret


add_array: ; wenn Primzahl, dann im Array abspeichern ...
push rax ; ... wir machen naemlich eine Liste.
nop
nop
nop
nop
cmp rsi, 11
jbe toosmallfortable
mov rax, qword [p_index] 
inc rax ; Max-Index der Liste erhöhen
mov qword [p_index], rax
mov qword [p_array+rax*8], rsi ; und am Array-Ende die neue Primzahl anheften. RSI
toosmallfortable:
pop rax
ret


get_wu: ; berechnet die Wurzel der zu untersuchenden Zahl,
fild qword [para_w] ; um nicht unnötig viele Tests zu haben.
fsqrt
fisttp qword [res]
mov rbx, [res]
inc rbx
ret

get_index_of_array:
push rax
mov rax, 0
index_erhoehen:
inc rax
cmp qword [p_array+rax*8], rbx
jl index_erhoehen
mov r15, rax
pop rax
ret


check_prim:
push rax
push rdx
push rsi
push rdi
mov byte [primzahl_boolean], 0 ; just a boolean-Variable... "ist nicht prim"
mov rax, [para_w] ; the number to check
mov rsi, [para_w] ; the number to check
call get_wu ; bringt in rbx die Wurzel von para_w+1
call get_index_of_array ; bringt in r15 den Index im Array, von welchem aus runterwärts verglichen werden muss
nochmal:
mov rdi, qword [p_array+r15*8]
mov rax, rsi
dec r15
cmp r15,0 ; war zuerst 1   
je ende
xor rdx, rdx
div rdi ; teilt rax / rdi
cmp rdx,0
jnz nochmal ; solange noch prim, nach oben, weiter testen
mov byte [primzahl_boolean], 1
ende:
pop rdi
pop rsi
pop rdx
pop rax
ret




zeilensprung:
push rax
push rbx
push rcx
push rdx
push rsi
push rdi
mov rax, 4
mov rbx, 1
mov rcx, crlf
mov rdx, 2
int 128
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
ret



print_dez:
push rax
push rbx
push rcx
push rdx

;mov rax, [para_w]
xor rcx,rcx
mov rbx,10

schl1:
xor rdx,rdx
div rbx
push rdx
inc rcx
cmp rax,0

jnz schl1

schl2:
pop rdx
add dl,30h
mov [ziffer],dl
push rcx
mov rax, 4
mov rbx, 1
mov rcx, ziffer
mov rdx, 1
int 128
pop rcx
loop schl2

pop rdx
pop rcx
pop rbx
pop rax
ret






start2:   ; here starts the proggi

mov rcx,3   ; Number to start. hardcoded.

mov rax, 1
mov qword [rax*8+p_array], 2

mov rax, 2
mov qword [rax*8+p_array], 2

mov rax, 3
mov qword [rax*8+p_array], 3

mov rax, 4
mov qword [rax*8+p_array], 5

mov rax, 5
mov qword [rax*8+p_array], 7

mov rax, 6
mov qword [rax*8+p_array], 11
mov qword [p_index], rax


increase_further:
mov [para_w], rcx
call check_prim

cmp byte [primzahl_boolean], 1     ; Prime ?
je no_prime
mov rsi, [para_w]
call add_array
mov rax, [para_w]
call print_dez

call zeilensprung

;call zeige_tabelle     ; zum debuggen

no_prime:       ; no prime !
add rcx, 2
cmp rcx,200001 ; eigentlich 200001
jbe increase_further


mov rax,1
int 128




77
Programming with NASM / Re: Printing of floating point values
« Last post by andyz74 on October 26, 2023, 07:12:13 PM »
You can separate the integer part from the fractional part with cvttss2si or cvttsd2si, and subtract the original values to get the fractional part (remember to obtain the absolute values). Then, for integer part, you can obtain the # of decimal algarisms using log10, and divide the integer value by 10, in sequence, util you get a zero quotient - getting the actual algarisms... For the fractional part, you just need to multiply them by 10 (until get 0.0 or the # of algarisms you want).

There are faster ways...

Ah, many thanks, this is a good way to start! :-)
78
Programming with NASM / Re: Printing of floating point values
« Last post by fredericopissarra on October 26, 2023, 06:21:19 PM »
You can separate the integer part from the fractional part with cvttss2si or cvttsd2si, and subtract the original values to get the fractional part (remember to obtain the absolute values). Then, for integer part, you can obtain the # of decimal algarisms using log10, and divide the integer value by 10, in sequence, util you get a zero quotient - getting the actual algarisms... For the fractional part, you just need to multiply them by 10 (until get 0.0 or the # of algarisms you want).

There are faster ways...
79
Programming with NASM / Re: Printing of floating point values
« Last post by andyz74 on October 26, 2023, 05:22:32 PM »
Hello Frank, and thanks for the welcome-wishes! :-)

As I think all over it, i just need the printf for "seeing" my values. In fact I do not really need this written out. 
But the printf-function seems to be cabaple of interpreting and displaying the packed BCD-Values.

For example I wrote a piece of code, which calculates different squareroots, which are at least partly even, without floating point. These are moved to registers, where I want to see them with a debugger.  Nevertheless, I can't see my values in the register; I assume, they are BCD-packed, which I assume, printf could write them OR I find another solution. (For unpacking the packed BCD ?)

Code: [Select]
; calculates square root

; nasm -f elf64 fpu_sq_root.asm
; ld -s -o fpu_sq_root fpu_sq_root.o


[bits 64]

global _start
 
section .data
    _msg  db '                ',0ah
    len_msg equ $-_msg
    val1: dq 16  ;declare quad word (double precision)
    val2: dq 9  ;declare quad word (double precision)
    val3: dq 4  ;declare quad word (double precision)
    val4: dq 1  ;declare quad word (double precision)
    val5: dq 0  ;declare quad word (double precision)
    val6: dq 0.25  ;declare quad word (double precision)
    val7: dq 2.25  ;declare quad word (double precision)
    val8: dq 6.25  ;declare quad word (double precision)
    val9: dq 12.25  ;declare quad word (double precision)
 
section .bss
    res: resq 1     ;reserve 1 quad word for result
 
section .text
    _start:
    nop
    nop
    nop
    nop
    nop
   
    fld qword [val1] ;load value into st0
    fsqrt           ;compute square root of st0 and store in st0
    fst qword [res] ;store st0 in result
    mov rbx, [res]
    nop

    fld qword [val2] ;load value into st0
    fsqrt           ;compute square root of st0 and store in st0
    fst qword [res] ;store st0 in result
    mov rbx, [res]
    nop

    fld qword [val3] ;load value into st0
    fsqrt           ;compute square root of st0 and store in st0
    fst qword [res] ;store st0 in result
    mov rbx, [res]
    nop

    fld qword [val4] ;load value into st0
    fsqrt           ;compute square root of st0 and store in st0
    fst qword [res] ;store st0 in result
    mov rbx, [res]
    nop

    fld qword [val5] ;load value into st0
    fsqrt           ;compute square root of st0 and store in st0
    fst qword [res] ;store st0 in result
    mov rbx, [res]
    nop

    fld qword [val6] ;load value into st0
    fsqrt           ;compute square root of st0 and store in st0
    fst qword [res] ;store st0 in result
    mov rbx, [res]
    nop
   
    fld qword [val7] ;load value into st0
    fsqrt           ;compute square root of st0 and store in st0
    fst qword [res] ;store st0 in result
    mov rbx, [res]
    nop
   
    fld qword [val8] ;load value into st0
    fsqrt           ;compute square root of st0 and store in st0
    fst qword [res] ;store st0 in result
    mov rbx, [res]
    nop
   
    fld qword [val9] ;load value into st0
    fsqrt           ;compute square root of st0 and store in st0
    fst qword [res] ;store st0 in result
    mov rbx, [res]
    nop
 
nop
nop
nop

mov rax,1
int 80h
    ;end program


=> Squareroots of the val's are computed and one after each stored in RBX.
If I debug the program with radare2, I see senseless numbers in RBX.
Are they packed BCD? If yes, how to unpack ?

Greetz and thanks, Andy

PS : the many "nop" are for me to be able to get orientation while debugging...
80
Programming with NASM / Re: Printing of floating point values
« Last post by Frank Kotler on October 26, 2023, 02:34:58 AM »
Hi Andy,
Welcome to the forum!

I think there should be a way to get gcc to do what you want. Not really a "Nasm question" but you need to know the answer ! , You can print floats without the C library, too but it may not be the best use of your time.

I hope someone can cone up with the right command line to gcc. 

Best,
Frank


Pages: 1 ... 6 7 [8] 9 10