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..........
- 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
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.
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....
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
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
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
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
i did it that way for clarity :P
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:
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
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
adc ecx, 0
adc ecx,ecx
Hmmmm,
What wrong with using REAL8 floating point data types that DO work in the 64 bit range ?
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
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
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)
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?
Bignum functions need unsigned.
Dave.
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 startOutput (identical for MB + CRT):
x:qwPos 7FFFFFFF FFFFFFFF
s:qwPos 9223372036854775807
u:qwPos 9223372036854775807
x:qwNeg 80000000 00000000
s:qwNeg -9223372036854775808
u:qwNeg 9223372036854775808SetupMasmBasic27March14
q.zip is needed 8)
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