OSDev.org

The Place to Start for Operating System Developers
It is currently Sun May 31, 2020 3:32 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 13 posts ] 
Author Message
 Post subject: YASM/NASM define 80-bit variable
PostPosted: Wed Oct 02, 2019 9:03 am 
Offline
Member
Member
User avatar

Joined: Tue Mar 06, 2007 11:17 am
Posts: 1224
To define an 80-bit value we can do:

Code:
dt 0.0



How to do the same if I want to define an 80-bit bitwise variable?

_________________
http://www.ebay.com/usr/udocproject3 (Updated IP)
http://190.53.102.175/api/doc/en/ (My OS compatible with DOS)

(udocproject@yahoo.com)
-----------------------------
IP for hosts file (all domains):
190.53.102.175 api.exe


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Wed Oct 02, 2019 10:26 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 3755
Location: Chichester, UK
variable: rest 1


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Wed Oct 02, 2019 10:31 am 
Offline
Member
Member

Joined: Tue Mar 04, 2014 5:27 am
Posts: 1011
~ wrote:
To define an 80-bit value we can do:

Code:
dt 0.0


How to do the same if I want to define an 80-bit bitwise variable?


There are no bit/integer operations on 80-bit values in x86. You'll need to compose e.g. a 80-bit XOR using a 64-bit XOR and a 16-bit XOR.
Probably for this reason NASM's DT directive doesn't accept integer constants and requires floating point or packed BCD (the latter suffixed with p or prefixed with 0p, e.g. 33p or 0p33).
If your values are relatively small or simple patterns, you can just use a combination of two directives, e.g.:

Code:
dd bits63_0
dw bits79_64


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Fri Oct 04, 2019 1:42 am 
Offline
Member
Member
User avatar

Joined: Tue Mar 06, 2007 11:17 am
Posts: 1224
I've had to use:

Code:
dq 0000000000000000000000000000000000000000000000000000000000000000b ;0-63
dw                                                                 0000000000000000b ;64-80



or

Code:
dd 00000000000000000000000000000000b  ;0-31
dd                                 00000000000000000000000000000000b ;32-63
dw                                                                 0000000000000000b ;64-80




By now.

_________________
http://www.ebay.com/usr/udocproject3 (Updated IP)
http://190.53.102.175/api/doc/en/ (My OS compatible with DOS)

(udocproject@yahoo.com)
-----------------------------
IP for hosts file (all domains):
190.53.102.175 api.exe


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Fri Oct 04, 2019 2:01 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7461
Location: Germany
Smelling a X-Y problem here... what are you wanting a 80-bit variable for?

Are you, by any chance, trying to store a x86 extended precision floating point?

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Fri Oct 04, 2019 4:58 am 
Offline
Member
Member

Joined: Thu Jul 03, 2014 5:18 am
Posts: 76
Location: The Netherlands
Code:
resb 80

_________________
My blog: http://www.rivencove.com/


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Fri Oct 04, 2019 5:54 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 3755
Location: Chichester, UK
I think you mean

resb 10


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Mon Oct 07, 2019 3:27 am 
Offline
Member
Member

Joined: Thu Jul 03, 2014 5:18 am
Posts: 76
Location: The Netherlands
iansjack wrote:
I think you mean

resb 10


You're right! For some reason I read 80 bytes. #-o

_________________
My blog: http://www.rivencove.com/


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Sat Oct 12, 2019 3:34 pm 
Offline
Member
Member
User avatar

Joined: Tue Mar 06, 2007 11:17 am
Posts: 1224
Solar wrote:
Smelling a X-Y problem here... what are you wanting a 80-bit variable for?

Are you, by any chance, trying to store a x86 extended precision floating point?


I want to bulk-move 80 bytes of binary data with the FPU (from 8 10-byte registers).

I suspect it would be (and is) a great addition to CPU-intensive applications. Even old CPUs with FPU could move 2 bytes more per operation (and eight 10-byte registers) than with 64-bit instructions.

I already tested it and it's possible (all bits are preserved, or probably unknown ciphers could not be encoded so it can be used at the very least to move raw data or strings).

But you have to disable truncation/rounding, maybe some FPU interrupts and enable full precision.

It needs no special instructions and is even better than a 64-bit data move loop:

Code:
;It can make 0xFFFFFFFF iterations in
;around 1:09.05 minutes in a dual core
;at 3.4GHz (less than 1:12 minutes).
;;


;It could be extended with all GPRs
;to move through the destination pointer
;every 10 bytes (70 bytes for EAX,
;EBX, ECX, EDX, ESI, EDI, EBP and maybe
;ESP with which we address for the
;80-byte FPU stack)
;instead of subtracting a single one, or a
;2-pointer struct for the initial source and
;destination values for each general-purpose
;register.
;
;Param 1 -- Source register value
;Param 2 -- Destination register value
;;
%macro MICRO_LONG__move_80_bytes_with_x87_FPU 2

;Load the whole FPU stack:
;;
  add %1,10*7       ;Move to the last TWORD of the 8
  fld tword[%1]
  sub %1,10
  fld tword[%1]
  sub %1,10
  fld tword[%1]
  sub %1,10
  fld tword[%1]
  sub %1,10
  fld tword[%1]
  sub %1,10
  fld tword[%1]
  sub %1,10
  fld tword[%1]
  sub %1,10
  fld tword[%1]


;Copy 10 bytes at a time:
;;
  fstp tword[%2]
  add %2,10
  fstp tword[%2]
  add %2,10
  fstp tword[%2]
  add %2,10
  fstp tword[%2]
  add %2,10
  fstp tword[%2]
  add %2,10
  fstp tword[%2]
  add %2,10
  fstp tword[%2]
  add %2,10
  fstp tword[%2]



%endmacro


  ;;INIT: Initialize the FPU for this program
  ;;INIT: Initialize the FPU for this program
  ;;INIT: Initialize the FPU for this program
  ;;INIT: Initialize the FPU for this program

   ;Initialize the FPU to its default state and configuration
   ;after checking for pending unmasked floating-point exceptions:
   ;;
    finit

   ;Wait for any pending FPU operations
   ;or exceptions and clear any
   ;pending exceptions:
   ;;
    fclex

   ;Load new x87 Control Word
   ;into FPU control register:
   ;;
    fldcw [x87_FPU_New_Control_Word]



  ;;END:  Initialize the FPU for this program
  ;;END:  Initialize the FPU for this program
  ;;END:  Initialize the FPU for this program
  ;;END:  Initialize the FPU for this program






align 4,db 0                  
                   x87_FPU_New_Control_Word equ $+ImageBase-__data_RVA_Localize__
                         dw 0001111110111111b
;                              -__--_ -_-_-_
;                              ||  || ||||||
;                              ||  || ||||||
;                              ||  || ||||||
;                              ||  || ||||||
;                              ||  || ||||| ---- 0 - IM - Invalid Operation Interrupt Mask (exception):
;                              ||  || |||||               0: Generate INT/IRQ (disable handling at the FPU).
;                              ||  || |||||               1: Do not generate INT/IRQ (selected at initialization, enable handling at the FPU).
;                              ||  || |||||
;                              ||  || |||| ----- 1 - DM - Denormalized Interrupt Mask (exception):
;                              ||  || ||||                0: Generate INT/IRQ (disable handling at the FPU).
;                              ||  || ||||                1: Do not generate INT/IRQ (selected at initialization, enable handling at the FPU).
;                              ||  || ||||
;                              ||  || ||| ------ 2 - ZM - Zero Divide Interrupt Mask (exception):
;                              ||  || |||                 0: Generate INT/IRQ (disable handling at the FPU).
;                              ||  || |||                 1: Do not generate INT/IRQ (selected at initialization, enable handling at the FPU).
;                              ||  || |||
;                              ||  || || ------- 3 - OM - Overflow Interrupt Mask (exception):
;                              ||  || ||                  0: Generate INT/IRQ (disable handling at the FPU).
;                              ||  || ||                  1: Do not generate INT/IRQ (selected at initialization, enable handling at the FPU).
;                              ||  || ||
;                              ||  || | -------- 4 - UM - Underflow Interrupt Mask (exception):
;                              ||  || |                   0: Generate INT/IRQ (disable handling at the FPU).
;                              ||  || |                   1: Do not generate INT/IRQ (selected at initialization, enable handling at the FPU).
;                              ||  || |
;                              ||  ||  --------- 5 - PM - Precision Interrupt Mask (exception):
;                              ||  ||                     0: Generate INT/IRQ (disable handling at the FPU).
;                              ||  ||                     1: Do not generate INT/IRQ (selected at initialization, enable handling at the FPU).
;                              ||  ||
;                              ||  | ---------- 7 - IEM - Interrupt Enable Mask (global for INT bits 0-5):
;                              ||  |                      0: Enable interrupts.
;                              ||  |                      1: Disable interrupts (selected at initialization).
;                              ||  |
;                              ||   ---------- 8-9 - PC - Precision Control:
;                              ||                         00b: 24 bits (REAL4).
;                              ||                         01b: Unused.
;                              ||                         10b: 53 bits (REAL8).
;                              ||                         11b: 64 bits (REAL10, selected at initialization).
;                              ||
;                              | ----------- 10-11 - RC - Rounding Control:
;                              |                          00b: Round to nearest, or to even if equidistant (selected at initialization).
;                              |                          01b: Round down (towards -Infinity).
;                              |                          10b: Round up (towards +Infinity).
;                              |                          11b: Truncate (towards 0).
;                              |
;                               --------------- 12 - IC - Infinity Control (more modern CPUs always use -Infinity and +Infinity):
;                                                         0: Use unsigned Infinity (selected at initialization).
;                                                         1: Respect -Infinity and +Infinity.
;
;
;
;
;
;



Code:
;INIT: Main benchmark
;INIT: Main benchmark
;INIT: Main benchmark
;INIT: Main benchmark

  mov widecx,0
  mov widesi,source_10_byte_buffer_or_String_10_byte_end
  move widedi,dest_buffer
  align wideword_sz
  .tttt:

    MICRO_LONG__move_80_bytes_with_x87_FPU widesi,widedi


  dec widecx
  jnz .tttt


;END:  Main benchmark
;END:  Main benchmark
;END:  Main benchmark
;END:  Main benchmark


_________________
http://www.ebay.com/usr/udocproject3 (Updated IP)
http://190.53.102.175/api/doc/en/ (My OS compatible with DOS)

(udocproject@yahoo.com)
-----------------------------
IP for hosts file (all domains):
190.53.102.175 api.exe


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Sat Oct 12, 2019 9:59 pm 
Offline

Joined: Fri Oct 04, 2019 10:10 am
Posts: 18
If you're on something new enough to run at 3.4 ghz you can use the sse instructions and move 16 bytes at a time.

The rounding issues aside, certain mobile targeted x86 chips (jaguar) really don't like it if you use the old x87 fpu or mms instructions, and reserve register rename slots for them indefinitely.

If you're targeting something from the last 15 years, it is strongly recommended to just use the xmm regs for everything.


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Sun Oct 13, 2019 1:13 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 3755
Location: Chichester, UK
The 80-bit floating-point instructions are pretty slow compared to the integer or multimedia move instructions. I suspect that you have discovered the slowest way of moving memory.


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Sun Oct 13, 2019 1:50 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 1967
iansjack wrote:
I suspect that you have discovered the slowest way of moving memory.

According to these tables, with a bit of optimization it's pretty close to the fastest way to move memory on an 8088. I'm not sure it's possible to beat REP MOVSW though.

It's nowhere near the fastest option on any other CPU.


Top
 Profile  
 
 Post subject: Re: YASM/NASM define 80-bit variable
PostPosted: Sun Oct 13, 2019 2:57 pm 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 3755
Location: Chichester, UK
But you can't assume that an 8088 has a floating-point unit. Most of them didn't. So, on average, on an 8088 it just wouldn't work.

I have to admit that I wasn't considering obsolete processors.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Majestic-12 [Bot] and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group