The MASM Forum

General => The Campus => Topic started by: shaikkareem on March 27, 2014, 10:23:16 PM

Title: need help to manipulate 64-bit range numbers in masm32
Post by: shaikkareem on March 27, 2014, 10:23:16 PM
hi everyone............
i got a headache tiny problem with 32 bit value becoming as 64 bit value, let look below a tiny program

include \masm32\include\masm32rt.inc

   .data
   src1 dd ?
   src2 dd ?

   .code
start:
   mov eax,src1
   add eax,src2
   

exit
end start

here src1 and src2 are two 32 bit length in size, if i gave the two different or same number to src1 and src2. Then i move the value of src1 to the 'eax'
here both are 32 bit wide and no problem with them. Now while i add the src2 value to the eax, what if the range of result of addition exceed to range of eax that is the dword number get into 64bit number . what i do to catch if the value of addition get beyond the 32 bit range of eax and how masm32 treat it. is it the over flow relate to over flow flag. how i get the result of 64bit value from two 32 bit values.....
how to manipulate the 64bit numbers in masm32..........with registers, with all,can anybody help me..........
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: jj2007 on March 27, 2014, 10:51:19 PM
- put two numbers into your variables that will exceed 32 bits when added.
- insert an int 3 before the operation
- assemble and link
- launch the exe with Olly (http://www.ollydbg.de/version2.html)
- hit F9
- Olly will stop at the int 3
- now look at the flags, hit F7 and see how they change

You might consult the adc instruction in \Masm32\help\opcodes.chm
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: FORTRANS on March 28, 2014, 01:54:11 AM
Hi,

   Adding two 32-bit numbers can only create a 33-bit number as
a maximum value.  The extra bit will be in the Carry Flag if the
addition was unsigned.  If you are using signed addition, the
Overflow Flag will indicate the extra bit.  That is what jj2007 was
showing you what to look for.

HTH,

Steve N.
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: shaikkareem on March 28, 2014, 02:14:38 AM
Let hope on you that 'the addition of two 32 bit numbers only create 33bit number' if i print it on the console if it is loaded in eax register, it is showing the result -1. So how i can retrieve result from the unsigned numbers addition with the help of carry flag.
Now i got another on ,i declared a variable with the type qword. It is not initializing with the immediate value or with register help so how can i init it....
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: dedndave on March 28, 2014, 03:27:14 AM
the simplest way is probably to store the 64-bit value in memory
then display it using a 64-bit integer-to-ASCII-decimal routine

however, during intermediate operations, it is sometimes necessary to move the CF bit into a register
we might use RCL (rotate carry left) to shift the carry bit into the low bit of a zero register
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: TouEnMasm on March 28, 2014, 03:34:06 AM

To get many answers on calcul, you can made them in c,here a sample.

#include <windows.h>
#pragma comment(lib,"user32")

int a, b, star;   //integor declaration


//        Name: WinMain
// Description: Main entry point
//  Parameters: Application instance, previous instance, command line, show command
//     Returns: Return code
int WINAPI WinMain(HINSTANCE p_hInstance,HINSTANCE p_hPrevInstance,PSTR p_szCmdLine,int p_iCmdShow)
{

int retour;
DOUBLE diviseur = 50;
DOUBLE nombre = 200;
DOUBLE resultat = 0;
LPSTR pBuf;

resultat = nombre/diviseur;
pBuf = (LPSTR)malloc(200);

retour =resultat ;//val32 = (val64 >> 32); // get the high 32 bits
wsprintf(pBuf,"valeur resultat : %lu ",retour);
MessageBox(NULL,pBuf,"titre",MB_OK);
free(pBuf);
return 0;
}



Here the translate in asm with /FA
Quote
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.40219.01

   TITLE   E:\optimise\calcul.c
   .686P
   .XMM
   include listing.inc
   .model   flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

_DATA   SEGMENT
COMM   _a:DWORD
COMM   _b:DWORD
COMM   _star:DWORD
_DATA   ENDS
PUBLIC   ??_C@_05OBAOBAKA@titre?$AA@         ; `string'
PUBLIC   ??_C@_0BH@GCADHJGE@valeur?5resultat?5?3?5?$CFlu?5?$AA@ ; `string'
PUBLIC   __real@0000000000000000
PUBLIC   __real@4069000000000000
PUBLIC   __real@4049000000000000
PUBLIC   _WinMain@16
EXTRN   _free:PROC
EXTRN   __imp__MessageBoxA@16:PROC
EXTRN   __imp__wsprintfA:PROC
EXTRN   _malloc:PROC
EXTRN   __fltused:DWORD
EXTRN   __ftol2_sse:PROC
;   COMDAT ??_C@_05OBAOBAKA@titre?$AA@
; File e:\optimise\calcul.c
CONST   SEGMENT
??_C@_05OBAOBAKA@titre?$AA@ DB 'titre', 00H      ; `string'
CONST   ENDS
;   COMDAT ??_C@_0BH@GCADHJGE@valeur?5resultat?5?3?5?$CFlu?5?$AA@
CONST   SEGMENT
??_C@_0BH@GCADHJGE@valeur?5resultat?5?3?5?$CFlu?5?$AA@ DB 'valeur resulta'
   DB   't : %lu ', 00H            ; `string'
CONST   ENDS
;   COMDAT __real@0000000000000000
CONST   SEGMENT
__real@0000000000000000 DQ 00000000000000000r   ; 0
CONST   ENDS
;   COMDAT __real@4069000000000000
CONST   SEGMENT
__real@4069000000000000 DQ 04069000000000000r   ; 200
CONST   ENDS
;   COMDAT __real@4049000000000000
CONST   SEGMENT
__real@4049000000000000 DQ 04049000000000000r   ; 50
; Function compile flags: /Odtp /ZI
CONST   ENDS
;   COMDAT _WinMain@16
_TEXT   SEGMENT
_pBuf$ = -32                  ; size = 4
_resultat$ = -28               ; size = 8
_nombre$ = -20                  ; size = 8
_diviseur$ = -12               ; size = 8
_retour$ = -4                  ; size = 4
_p_hInstance$ = 8               ; size = 4
_p_hPrevInstance$ = 12               ; size = 4
_p_szCmdLine$ = 16               ; size = 4
_p_iCmdShow$ = 20               ; size = 4
_WinMain@16 PROC               ; COMDAT
; Line 38
   push   ebp
   mov   ebp, esp
   sub   esp, 96               ; 00000060H
   push   ebx
   push   esi
   push   edi
; Line 41
   fld   QWORD PTR __real@4049000000000000
   fstp   QWORD PTR _diviseur$[ebp]
; Line 42
   fld   QWORD PTR __real@4069000000000000
   fstp   QWORD PTR _nombre$[ebp]
; Line 43
   fldz
   fstp   QWORD PTR _resultat$[ebp]
; Line 46
   fld   QWORD PTR _nombre$[ebp]
   fdiv   QWORD PTR _diviseur$[ebp]
   fstp   QWORD PTR _resultat$[ebp]
; Line 47
   push   200               ; 000000c8H
   call   _malloc
   add   esp, 4
   mov   DWORD PTR _pBuf$[ebp], eax
; Line 49
   fld   QWORD PTR _resultat$[ebp]
   call   __ftol2_sse
   mov   DWORD PTR _retour$[ebp], eax
; Line 51
   mov   eax, DWORD PTR _retour$[ebp]
   push   eax
   push   OFFSET ??_C@_0BH@GCADHJGE@valeur?5resultat?5?3?5?$CFlu?5?$AA@
   mov   ecx, DWORD PTR _pBuf$[ebp]
   push   ecx
   call   DWORD PTR __imp__wsprintfA
   add   esp, 12               ; 0000000cH
; Line 52
   push   0
   push   OFFSET ??_C@_05OBAOBAKA@titre?$AA@
   mov   eax, DWORD PTR _pBuf$[ebp]
   push   eax
   push   0
   call   DWORD PTR __imp__MessageBoxA@16
; Line 53
   mov   eax, DWORD PTR _pBuf$[ebp]
   push   eax
   call   _free
   add   esp, 4
; Line 55
   xor   eax, eax
; Line 56
   pop   edi
   pop   esi
   pop   ebx
   mov   esp, ebp
   pop   ebp
   ret   16               ; 00000010H
_WinMain@16 ENDP
_TEXT   ENDS
END


Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: dedndave on March 28, 2014, 03:49:32 AM
one of the calls to crt_sprintf should work
i'm not sure whether it allows qwords to be passed, so i show it both ways
    INCLUDE     \masm32\include\masm32rt.inc

    .DATA

szFormat db '%I64u',0

    .DATA?

qwValue  dq ?
szBuffer db 24 dup(?)

    .CODE

start:
    mov     eax,80000000h
    mov     edx,80000000h
    xor     ecx,ecx

    add     eax,edx
    adc     ecx,0
    mov dword ptr qwValue,eax
    mov dword ptr qwValue+4,ecx

    INVOKE  crt_sprintf,offset szBuffer,offset szFormat,qwValue
    print   offset szBuffer,13,10

    INVOKE  crt_sprintf,offset szBuffer,offset szFormat,dword ptr qwValue, dword ptr qwValue+4
    print   offset szBuffer,13,10

    inkey
    INVOKE  ExitProcess,0

    END     start


i guess either method works   :biggrin:

EDIT: modified the code
1) corrected include path
2) added print lines
3) added inkey line
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: jj2007 on March 28, 2014, 05:22:29 AM
Dave is found guilty of trashing valuable registers 8)
   mov eax, 80000000h
   mov edx, 80000000h
   add eax, edx
   adc dword ptr qwValue+4, 0
   mov dword ptr qwValue, eax

Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: dedndave on March 28, 2014, 05:30:43 AM
i did it that way for clarity   :P
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: jj2007 on March 28, 2014, 05:39:44 AM
I know ;-)

What I didn't know was that adc mem, imm works :P
Which is kind of logical because adc is just a variant of add,
but I never used it before. I keep learning :biggrin:
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: shaikkareem on March 28, 2014, 03:18:28 PM
hey all i just want to knw that did you all ever saw the div,mul,cdq opcodes using edx & eax registers in combine for making 64-bit range. is there any possibility to use them in our programs.....as asm does
and another thing is adc opcode says 'Sums two binary operands placing the result in the destination.
If CF is set, a 1 is added to the destination.' really can't understand with 33 bit case and 64 bit case as my you all said.
now i didn't get the answer for problem.....
how to initialize a qword declared variable......directly or indirectly
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: MichaelW on March 28, 2014, 03:36:24 PM
Shorter coding:

include \masm32\include\masm32rt.inc
.code
start:
    mov eax, 80000000h
    mov edx, 80000000h
    xor ecx, ecx
    add eax, edx
    adc ecx, 0
    printf("%I64u\n\n",ecx::eax)
    inkey
    exit
end start


4294967296
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: sinsi on March 28, 2014, 03:48:31 PM
adc ecx, 0
adc ecx,ecx

Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: hutch-- on March 28, 2014, 04:00:43 PM
Hmmmm,

What wrong with using REAL8 floating point data types that DO work in the 64 bit range ?
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: MichaelW on March 28, 2014, 05:56:24 PM

include \masm32\include\masm32rt.inc
.686
.XMM
.data
    qw0  dq       2222222222222222h
    qw1  dq       0
    r8   REAL8    ?
    r10  REAL10   ?
.code
start:

    ; Here qw0 is stored as a REAL8 and reloaded,
    ; reducing the value to a 53-bit precision.

    fild    qw0
    fstp    r8
    fld     r8
    fistp   qw1
    printf("%I64Xh\n",qw1)

    ; Here qw0 is stored as a REAL10 and reloaded,
    ; maintaining the full 64-bit precision.

    fild    qw0
    fstp    r10
    fld     r10
    fistp   qw1
    printf("%I64Xh\n\n",qw1)

    ; Windows sets the FPU for 53-bit precision, so the
    ; fadd result gets rounded to a 53-bit precision.

    fild    qw0
    fild    qw0
    fadd
    fistp   qw1
    printf("%I64Xh\n\n",qw1)

    ; Set the FPU for 64-bit precision.

    finit

    fild    qw0
    fild    qw0
    fadd
    fistp   qw1
    printf("%I64Xh\n",qw1)

    movq    mm0, qw0
    paddq   mm0, mm0
    movq    qw1, mm0
    printf("%I64Xh\n",qw1)

    movq    xmm0, qw0
    paddq   xmm0, xmm0
    movq    qw1, xmm0
    printf("%I64Xh\n\n",qw1)

    inkey
    exit
   
end start


2222222222222200h
2222222222222222h

4444444444444400h

4444444444444444h
4444444444444444h
4444444444444444h
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: qWord on March 28, 2014, 06:20:32 PM
Even if the FPU internally can represent 64 bit unsigned integers (QWORD), the load and store instructions support only singed integers.
.data
    qw QWORD 7fffffffffffffffh
.code
finit
fld1
fild qw
fscale  ; st = st*2
fistp qw ; invalid operation (masked) -> qw = 8000000000000000h = -9223372036854775808
fstp st
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: MichaelW on March 29, 2014, 12:34:02 AM
Quote from: qWord on March 28, 2014, 06:20:32 PM
Even if the FPU internally can represent 64 bit unsigned integers (QWORD), the load and store instructions support only singed integers.

Yes, I had forgotten that, tested by unmasking the interrupt. I think the problem could be corrected by prefixing the operand with SQWORD PTR, but unfortunately ML 6.15 apparently does not recognize SQWORD.

;==============================================================================
include \masm32\include\masm32rt.inc
.686
;==============================================================================

;-----------------------------------------
; Values for the FPU interrupt mask bits.
;-----------------------------------------

FIM_INVALID      equ 1
FIM_DENORMALIZED equ 2
FIM_ZERODIVIDE   equ 4
FIM_OVERFLOW     equ 8
FIM_UNDERFLOW    equ 16
FIM_PRECISION    equ 32
FIM_ANY          equ 63

;--------------------------------------------------------
; This macro selectively clears the FPU interrupt masks.
; Example usage: FCLEARIM FIM_ZERODIVIDE or FIM_OVERFLOW
;--------------------------------------------------------

FCLEARIM MACRO maskbits
    push eax
    fstcw [esp]
    pop eax
    and ax, NOT (maskbits)
    push eax
    fldcw [esp]
    pop eax
ENDM

;==============================================================================
.data
    qw QWORD 7fffffffffffffffh
.code
;==============================================================================
start:
;==============================================================================

    finit
    FCLEARIM FIM_INVALID
    inkey
    fld1
    fild qw
    fscale  ; st = st*2
    fistp qw ; invalid operation (masked) -> qw = 8000000000000000h = -9223372036854775808
    fstp st

    inkey
    exit
;==============================================================================
end start

#define STATUS_FLOAT_DENORMAL_OPERAND  ((NTSTATUS)0xC000008DL)
#define STATUS_FLOAT_DIVIDE_BY_ZERO    ((NTSTATUS)0xC000008EL)
#define STATUS_FLOAT_INEXACT_RESULT    ((NTSTATUS)0xC000008FL)
#define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS)0xC0000090L)
#define STATUS_FLOAT_OVERFLOW          ((NTSTATUS)0xC0000091L)
#define STATUS_FLOAT_STACK_CHECK       ((NTSTATUS)0xC0000092L)
#define STATUS_FLOAT_UNDERFLOW         ((NTSTATUS)0xC0000093L)

Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: jj2007 on March 29, 2014, 01:01:33 AM
Quote from: MichaelW on March 29, 2014, 12:34:02 AMI think the problem could be corrected by prefixing the operand with SQWORD PTR, but unfortunately ML 6.15 apparently does not recognize SQWORD.

Jwasm and higher Masm versions do recognise SQWORD, but that doesn't change the encoding.

Str$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186) and printf() can handle 8000000000000000h, the latter can even print it signed. Another question is how useful that is - positive qwords are useful for file sizes etc, but who needs a negative QWORD?
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: KeepingRealBusy on March 29, 2014, 02:13:11 AM
Bignum functions need unsigned.

Dave.
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: jj2007 on March 29, 2014, 02:45:35 AM
Quote from: KeepingRealBusy on March 29, 2014, 02:13:11 AM
Bignum functions need unsigned.

Dave,

I had a suspicion that somebody would claim it's important ;-)

It was easier than I thought:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
.data
qwPos      dq 7fffffffffffffffh      ; highest positive number
qwNeg      dq 8000000000000000h      ; lowest negative number
  Init
  deb 4, "MasmBasic deb macro - see also Str$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1186):", x:qwPos, s:qwPos, u:qwPos, x:qwNeg, s:qwNeg, u:qwNeg
  Print CrLf$, "CRT printf():"
  printf("\nx:qwPos\t\t%I64X\ns:qwPos\t\t%I64i\nu:qwPos\t\t%I64u", qwPos, qwPos, qwPos)
  printf("\nx:qwNeg\t\t%I64X\ns:qwNeg\t\t%I64i\nu:qwNeg\t\t%I64u", qwNeg, qwNeg, qwNeg)
  Exit
end start


Output (identical for MB + CRT):
x:qwPos         7FFFFFFF FFFFFFFF
s:qwPos         9223372036854775807
u:qwPos         9223372036854775807
x:qwNeg         80000000 00000000
s:qwNeg         -9223372036854775808
u:qwNeg         9223372036854775808


SetupMasmBasic27March14q.zip is needed 8)
Title: Re: need help to manipulate 64-bit range numbers in masm32
Post by: dedndave on March 29, 2014, 03:49:11 AM
Quote from: KeepingRealBusy on March 29, 2014, 02:13:11 AM
Bignum functions need unsigned.

wouldn't that depend on the bignum library being used ?
it seems to me that unsigned functions are also available
sure - for crypto stuff, unsigned seems logical, but not for math