Recent Posts

Pages: [1] 2 3 ... 10
1
Programming with NASM / Re: Printing of floating point values
« Last post by andyz74 on March 27, 2025, 02:07:47 PM »
I read a bit about the comiss command and the flags that are set, if there were failures, but to be honest, I am absolutely not sure, if this is the right way.
2
Programming with NASM / Re: Printing of floating point values
« Last post by fredericopissarra on March 25, 2025, 09:44:06 PM »
Ah, I got it. You decrease the fractional part after each loop and check with the
Comiss xmm0, xmm3
If it gets no more smaller...   This is nice. :-)
Of... since it seems you didn't got the three potential bugs there here they are:
  • What will happen if the value is negative?
  • What will happen if the value is too big (like bigger then 264-1?
  • Whay will happen if the value is a NaN?
There is a simple way to fix this... I'll leave it to you...
3
Programming with NASM / Re: Printing of floating point values
« Last post by andyz74 on March 23, 2025, 04:42:04 PM »
Ah, I got it. You decrease the fractional part after each loop and check with the
Comiss xmm0, xmm3
If it gets no more smaller...   This is nice. :-)
4
Programming with NASM / Re: Printing of floating point values
« Last post by andyz74 on March 22, 2025, 06:42:50 PM »
OK, I will look and test it these days and be like every time thankful for reading programs from other people, that I can learn. :-)

But for now, one question :
You have in your program the possibility to control the number of digits after the point. (with EDI) .
EDI = 0 makes ALL numbers after the point.

So, how do we now, how much ALL is? Is there a special sign, that we see, the end of the numbers?

Yes, I overlooked your code, but couldn't find the answer ... lack of knowledge. :-(

Greetz from Germany, Andy
5
Programming with NASM / Re: Printing of floating point values
« Last post by fredericopissarra on March 22, 2025, 12:38:03 PM »
Very good... Notice that values like 123.456789 aren't exact in floating point... You can tweak a little bit and create a routine to present the value in a desired precision... Here's an example (it has a small bug, but I'll leave it to you to discover and fix it):
Code: [Select]
; main.asm
  bits  64
  default rel

  section .text

  extern printfloat

  global  _start
_start:
  movss xmm0, [value]
  xor   edi, edi      ; maximum precision.
  call  printfloat

  ; Prints a newline.
  mov   eax,1
  mov   edi,eax
  lea   rsi,[crlf]
  mov   edx,eax
  syscall

  ; Exits the program with errorcode 0.
  mov   eax,60
  xor   edi,edi
  syscall

  section .rodata

  align 4
value:
  dd  123.45678         ; this isn't exact in floating point!

crlf:
  db  `\n`

  section .note.GNU-stack noexec
Code: [Select]
; float.asm
  bits  64
  default rel

  section .text

  global  printfloat

; Input: XMM0 = x; EDI = precision (maximum # of fractional digits - 0 if all).
printfloat:
  cvttss2si r9, xmm0
  mov       byte [rsp-1], 0
  mov       r8d, edi
  lea       rsi, [rsp-1]
  mov       r10d, 0xcccccccd      ; 1/10 scaled.
  mov       edx, r9d

  align 4
.loop1:
  mov       eax, edx
  mov       ecx, edx
  sub       rsi, 1

  imul      rax, r10
  shr       rax, 35               ; EAX = n / 10.
  lea       edi, [rax+rax*4]
  add       edi, edi
  sub       ecx, edi              ; ECX = n % 10.

  add       ecx, '0'
  mov       [rsi], cl
  mov       ecx, edx
  mov       edx, eax
  cmp       ecx, 9                ; reminder sill > 9?
  ja        .loop1                ; yes, stay in the loop.

  mov       eax, 1
  mov       rdx, rsp    ; calc the string size.
  sub       rdx, rsi    ;
  mov       edi, eax
  syscall

  mov       eax,1
  mov       edi,eax
  mov       edx,eax
  lea       rsi, [dot]
  syscall

  pxor      xmm1, xmm1
  mov       r9d, r9d
  cvtsi2ss  xmm1, r9
  subss     xmm0, xmm1
  pxor      xmm1, xmm1
  cvttss2si rdx, xmm0
  mov       edx, edx
  cvtsi2ss  xmm1, rdx
  subss     xmm0, xmm1

  movss     xmm2, [ten]
  mov       r9d, r8d
  lea       rsi, [rsp-1]
  pxor      xmm3, xmm3

  align 4
.loop2:
  mulss     xmm0, xmm2
  pxor      xmm1, xmm1
  mov       edx, edi
  cvttss2si ecx, xmm0
  movsx     eax, cl
  add       ecx, '0'
  cvtsi2ss  xmm1, eax
  mov       [rsi], cl
  mov       eax, edi
  subss     xmm0, xmm1
  syscall

  ; Precision testing...
  test      r8d, r8d
  je        .skip
  sub       r9d, 1
  je        .exit
.skip:

  ; if fractional part isn't zero yet...
  comiss    xmm0, xmm3
  jne       .loop2      ; stay in the loop.

.exit:
  ret

  section .rodata

dot:
  db  '.'

  align 4
ten:
  dd    10.0

  section .note.GNU-stack noexec
Code: [Select]
$ nasm -felf64 main.asm -o main.o
$ nasm -felf64 float.asm -o float.o
$ ld -s -o main main.o float.o
$ ./main
123.45677947998046875

[]s
Fred
6
Programming with NASM / Re: Printing of floating point values
« Last post by andyz74 on March 20, 2025, 05:12:15 PM »
As I am on my way to become the GodMaster of Assembly ... (just joking...;-) )   I gave it another try and it works now for me.  Just as example, that it can be done.

It is a quick and dirty solution, maybe for purpose of checking values while developing, in a macro or *.inc-file

(Linux, 64 bit)

Code: [Select]
; try to print floating-point values via sse2

; nasm -f elf64 float-print.asm && ld -o float-print float-print.o


[bits 64]

global _start
 
section .data
   
    val1 dq 123.454789  ;declare quad word (double precision)
zehn dq 10.0
ziffer db 0
crlf db 13,10
dezp db '.'

section .text

_start:
    call newline
    mov r9, 1 ; r9 starts to count the numbers after decimalpoint we want to write
    movsd xmm1, qword [val1] ; our value, we want to write
    movsd xmm2, xmm1
    cvttsd2si rax, xmm2 ; rax is now val1 without numbers after decimalpoint
    call print_dez
call dez_point
  repeat_it:
cvtsi2sd xmm3, rax ; load the truncated value in xmm3
    subsd xmm2, xmm3 ; xmm2 is now the value behind the decimalpoint
    mulsd xmm2, [zehn] ; multiplic. by ten. (so get one number before the decimalpoint
    cvttsd2si rax, xmm2 ; rax is the number before the decimalpoint (only one number)
    call print_dez ; print this number
    inc r9
    cmp r9, 5 ;  <===   check if the wanted amount of "Nachkommastellen" is reached
    jle repeat_it
   
call newline

mov rax,60
syscall ;end program





print_dez: ; in rax should be the number to write
push rax
push rbx
push rcx
push rdx

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, 1 ; Funktionsnummer : schreiben
mov rdi, 1 ; auf STDOUT
mov rsi, ziffer ; was schreiben wir
mov rdx, 1 ; wieviel Zeichen
syscall
pop rcx
loop schl2

pop rdx
pop rcx
pop rbx
pop rax
ret


dez_point: ; just to write the point.
push rax
push rdx
mov rax, 1 ; Funktionsnummer : schreiben
mov rdi, 1 ; auf STDOUT
mov rsi, dezp ; was schreiben wir
mov rdx, 1 ; wieviele Zeichen
syscall
pop rdx
pop rax
ret


newline:
push rax
push rdx
mov rax, 1 ; Funktionsnummer : schreiben
mov rdi, 1 ; auf STDOUT
mov rsi, crlf ; was schreiben wir
mov rdx, 2 ; wieviele Zeichen
syscall
pop rdx
pop rax
ret
7
Other Discussion / Re: framebuffer problem
« Last post by fredericopissarra on March 15, 2025, 04:49:50 PM »
a) if i have declared my points as integer values like "mydata dq 100" or whatever, I should not load them like "movsd xmm0, qword [mydata]" but with  "cvtsi2sd xmm0, qword [mydata]"
If you intend to use this data as a double, yes.

Quote from: andyz74
b) if I really work with my data as integer, they will get after a few rotation-calculations very fast unexact by the truncation/rounding.  After a 360 degree-rotation in 360 steps I will have no more a cube, but some totally other formation. ;-)    => Will have to do this with floating-point (also the storing of the coordinates)
Floating point is ALWAYS an approximation. Most exact fractional values in decimal cannot be exactly represented in binary...

[]s
Fred
8
Other Discussion / Re: framebuffer problem
« Last post by andyz74 on March 10, 2025, 04:24:00 PM »
I found out the following by myself : 

a) if i have declared my points as integer values like "mydata dq 100" or whatever, I should not load them like "movsd xmm0, qword [mydata]" but with  "cvtsi2sd xmm0, qword [mydata]"

b) if I really work with my data as integer, they will get after a few rotation-calculations very fast unexact by the truncation/rounding.  After a 360 degree-rotation in 360 steps I will have no more a cube, but some totally other formation. ;-)    => Will have to do this with floating-point (also the storing of the coordinates)
9
Other Discussion / Re: framebuffer problem
« Last post by andyz74 on March 06, 2025, 10:33:37 PM »
So, I am trying my luck with sdl2.  A llittle cube defined by 8 points and the lines between it...  Moving works, but the rotating stuff isn't working, it calculates wrong values.
Because of the sinus and cosinus, I had to go with sse2, but something seems to be wrong.

I have my data like this :
Quote
section .data
xs    dq 0,0,0,0,0,0,0,0,0,0,0,0
ys  dq 0,0,0,0,0,0,0,0,0,0,0,0
points resq 24
tempx dq 0
tempy dq 0
tempz dq 0



                              ; reminder 960 x 720 window, haelfte 480 / 360
point dq    -100, -100, 300,
dq         100, -100, 300,
dq         -100, 100, 300,
dq         100, 100, 300,
dq         -100, -100, 500,
dq         100, -100, 500,
dq         -100, 100, 500,
dq         100, 100, 500   


yaussen dq 700                                 ; war erst 900 und 400
yscreen dq 100                                 ; reminder 960 x 720 window, haelfte 480 / 360

cos1 dq 0.9998477                     ; 0.9998477*x - 0.0174524*z;
sin1 dq 0.0174524
...the point-table will be written to the points-array.  Works, shifting to left, right, up, down, and in the depth worksall, but than comes a try of rotation ...

Quote
roty1:
   push rcx
   push r15
   mov rcx, 0
   nochmal8:                           ; tempx:= 0.9998477*x - 0.0174524*z
   movsd xmm0, qword [points+rcx*8]         ; load  x coordinate in xmm0
   movsd xmm1, qword [cos1]               ; load cos 1 from table in xmm1
   mulsd xmm0, xmm1                     ; multiply xmm0 and xmm1, store in xmm0
   movsd xmm2, qword [points+rcx*8+16]        ; load  z coordinate in xmm2
   movsd xmm3, qword [sin1]               ; load sin 1 from table in xmm3
   mulsd xmm2, xmm3                     ; multiply xmm2 and xmm3, store in xmm2
   subsd xmm0, xmm2                     ; subtract xmm2 from xmm0, store in xmm0
   mov r15, 0
   cvtsd2si r15, xmm0                     ; convert xmm0 to integer and store in r15
   mov qword [tempx], r15                  ; store tempx

                                    ; tempz:= 0.0174524*x + 0.9998477*z
   movsd xmm0, qword [points+rcx*8]         ; load  x coordinate in xmm0
   movsd xmm1, qword [sin1]               ; load sin 1 from table
   mulsd xmm0, xmm1                     ; multiply and store in xmm0
   movsd xmm2, qword [points+rcx*8+16]        ; load  z coordinate
   movsd xmm3, qword [cos1]               ; load cos 1 from table
   mulsd xmm2, xmm3                     ; multiply and store in xmm2
   addsd xmm0, xmm2                     ; add xmm0 and xmm2, store in xmm0
   mov r15, 0
   cvtsd2si r15, xmm0                     ; convet xmm0 to integer and store in r15
   mov qword [tempz], r15                  ; store tempz
   
   mov r15, 0
   mov   r15, [tempx]
   mov [points+rcx*8], r15                  ; write the new x coordinate to table
   mov r15, 0
   mov   r15, [tempz]
   mov [points+rcx*8+16], r15               ; same for z coordinate
   

   inc rcx
   inc rcx
   inc rcx
   cmp rcx, 24                           ; eight point in the cube, each with three coordinates...
   jne nochmal8

   pop r15
   pop rcx
ret
Rotation by y.
If I let calculate the stuff in Excel, I have good valuaes, but the conversion in Assembly-Code does not get me the right values.

Does anybody see obvious failures in the code?

Thanks in advance, Andy from the nightly sleeping Germany
10
Other Discussion / Re: framebuffer problem
« Last post by andyz74 on February 25, 2025, 05:10:06 PM »
I will test it "as last option" with breakpoints, but I think, it might be easier for me to comment out the sdl and graphic stuff, so I have only the calculating part working.  I just want to control my calculated coordinates by hand.  This should work.

(If i get it to work I surely will be here in some days to ask you for faster and better calculating algorithms. ;-) )

 
Pages: [1] 2 3 ... 10