Hi there can any body show me how to divide 9 by 2 and get 4.5 ?
I get 4 the Remainder is lost :(
Thank You !
include \masm32\include\masm32rt.inc
division proto
.data
caption db "division With Remainder Example", 0
Format db "%d",0
var1 dd 9h ; binary values
var2 dd 2h ; binary values
buffer db 32 dup(0)
.data?
finalVal dword ?
.code
Start:
invoke division
invoke MessageBox, 0, addr buffer, addr caption, MB_ICONQUESTION + MB_OK
invoke ExitProcess, 0
division Proc
mov eax, var1
mov ebx, var2
sub edx, edx ;set edx to zero
div ebx
mov finalVal,eax ; store the result
invoke wsprintf, addr buffer, addr Format, eax
xor eax,eax
ret
division endp
end Start
you must use the FPU (or SSEx) to get floating point results:
LOCAl x:REAL8
fld FP8(9.0)
fdiv FP8(2.0) ; (commonly you would multiply by 0.5)
fstp x
fnc crt_printf,"%.8G\n",x
the remainder is inside EDX variable.. which is in this case is 1 (one).
Quote from: hfheatherfox07 on January 06, 2013, 12:51:16 AM
Hi there can any body show me how to divide 9 by 2 and get 4.5 ?
- multiply by 5
- convert to string (45)
- move last byte into al (it's 5)
- insert a "." into that position
- move al right after the dot
Quote from: qWord on January 06, 2013, 01:55:45 AM
you must use the FPU (or SSEx) to get floating point results:
well - maybe so
but you can do "fixed point" math, as well
if you are always going to be dividing by a power of 2, it's not too difficult to get fast results using shift
binary numbers may have a decimal point, the same as decimal numbers
10101.0101
in this example, the bits before the decimal point represent 16, 8, 4, 2, 1 (decimal)
the bits after the decimal point represent 0.5, 0.25, 0.125, 0.0625 (decimal)
when you use SHR EAX,1 to divide the value in EAX by 2, the 1's bit is shifted into the carry flag
in this case, the carry flag represents the "0.5" bit
it can be recovered into another register and be interpreted as such
if you wanted to use a similar method to divide by 4 or 8 (etc), you could use the SHRD and SHR instructions
Quote from: dedndave on January 06, 2013, 03:13:58 AMbut you can do "fixed point" math, as well
he can also use his fingers to get it :icon_rolleyes:
:biggrin:
hey - we have to giver her options - lol
besides, a little understanding of binary math is a good thing :t
Quote from: dedndave on January 06, 2013, 03:18:10 AMhey - we have to giver her options - lol
besides, a little understanding of binary math is a good thing :t
good to know, but not needed for architectures that comes with instructions for FP arithmetic.
(For me fixed point math is this "Microcontroller and FPAG related stuff")
...and fingers :lol:
Add your toes, and you can arrive at 20 8)
20 ? - lol
don't you mean 1111111111.1111111111 :P
i don't believe you have a "handle" on this binary thing, Jochen :lol:
If one can live with 10 finger, 5 toes and an implicit limb of precision, he may use one foot as exponent :P
Quote from: qWord on January 06, 2013, 01:55:45 AM
you must use the FPU (or SSEx) to get floating point results:
LOCAl x:REAL8
fld FP8(9.0)
fdiv FP8(2.0) ; (commonly you would multiply by 0.5)
fstp x
fnc crt_printf,"%.8G\n",x
Hi all and thank you for the replies ....
What I am trying to do is use it when one of the numbers is unknown from a buffer ...
9/2 was just a random example ....
If I use a buffer how can I use use floating-point initializer ?
So 9 instead of 9.0 ???
I could not get qwords example to work with a messageBox Only Console
This is what I want it for
I want the answer here to have 2 decimal reminder
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
MsgCaption db "PUTER TIME",0
format db "Your puter has run %d:hours since the last boot, give it a break!",0
.data?
Buffer db 1024 dup (?)
szHoursVal dword ?
.code
start:
invoke GetTickCount
;Hours
mov szHoursVal,eax ; store the result of GetTickCount in eax
mov ebx,3600000
sub edx, edx ;set edx to zero
div ebx
invoke wsprintf,addr Buffer,addr format, eax
invoke MessageBox, NULL, addr Buffer, addr MsgCaption, MB_ICONASTERISK
invoke ExitProcess,NULL
end start
I am seeing the same questing posed here :
http://stackoverflow.com/questions/10570453/intel-x86-assembly-collecting-remainders-of-a-division
http://stackoverflow.com/questions/8231882/how-to-implement-the-mod-operator-in-assembly
http://stackoverflow.com/questions/8971627/masm-using-registers-as-expressions-between-mod-operator
I do not get the responses ?
How do you use mod ?
Thank You
Quote from: hfheatherfox07 on January 07, 2013, 07:21:50 PM
How do you use mod ?
Thank You
I use div (http://docs.oracle.com/cd/E19957-01/816-1323/instructionset-43/index.html).
Here's the code (FASM syntax, anyway)
format PE console 4.0
entry main
include 'win32a.inc'
section '.data' data readable writeable
num1 dd 27
num2 dd 4
fmt db "%d", 13, 10, 0
section '.code' code readable executable
main:
xor edx, edx
mov eax, [num1]
mov ecx, [num2]
div ecx
cinvoke printf, fmt, edx
invoke ExitProcess, 0
section '.idata' import data readable
library kernel32,'kernel32.dll', msvcrt,'msvcrt.dll'
import kernel32, ExitProcess,'ExitProcess'
import msvcrt, printf, 'printf'
It calculates 27 mod 4, which yields 3.
Sorry I thought mod could be used to obtain remainder
Which is what I am interested in doing
http://stackoverflow.com/questions/8971627/masm-using-registers-as-expressions-between-mod-operator
My understanding is that eax has the number and edx has the remainder
It seems like that you mean the fractional part of a real number, when talking about the remainder.
So the question is: do you need the that for further calculation or just for printing? In the second case, simply make a floating point calculation and then use the CRT to format the number in a string buffer:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\msvcrt.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\msvcrt.lib
.data
MsgCaption db "PUTER TIME",0
format db "Your puter has run %.4G:hours since the last boot, give it a break!",0
.data?
szBuffer db 1024 dup (?)
iTicks SDWORD ?
r8Ticks REAL8 ?
.const
r8HoursPerTicks REAL8 2.777777777777777778E-7 ; 1/3600000
; iTicksPerHour SDWORD 3600000
.code
start:
invoke GetTickCount
mov iTicks,eax
fild iTicks
fmul r8HoursPerTicks
;fidiv iTicksPerHour ; bad code
fstp r8Ticks
invoke crt_sprintf,ADDR szBuffer,ADDR format,r8Ticks ; the CRT only supports REAL8 here
invoke MessageBox, NULL, addr szBuffer, addr MsgCaption, MB_ICONASTERISK
invoke ExitProcess,NULL
end start
QuoteI want the answer here to have 2 decimal reminder
the easy way is to multiply the value by 100
or - divide the divisor by 100, if it is evenly divisable
or - some combination
either way, the result is, your quotient will be 100 x the real answer
now, convert it as an integer and stick a decimal point in there :P
Quote from: dedndave on January 08, 2013, 01:55:56 AM
the easy way is to multiply the value by 100
or - divide the divisor by 100, if it is evenly divisable
or - some combination
You could refine that a bit to allow for a larger dividend .
xor edx, edx
mov eax, 20 ; <- divide this (32bit)
mov ecx, 6 ; <- by this (24bit only)
div ecx ; eax =2
mov eax, edx
imul eax, 100
xor edx, edx
div ecx ; eax =33
.
xor edx, edx
mov eax, 9 ; <- divide this (32bit)
mov ecx, 2 ; <- by this (24bit only)
div ecx ; eax =4
mov eax, edx
imul eax, 100
xor edx, edx
div ecx ; eax =50 (ALWAYS 2 digits)
; this is one way how to get rid of 0
mov edx, 0cccccccdh
mov ecx, eax
mul edx
shr edx, 3
mov eax, edx
imul eax, 10
cmp eax, ecx
cmovnz edx, ecx ; edx =5 (or =33 in previous example)
You can also go this way but if you run this example you are in big trouble because result of division will not fit into 32bit value. In addition, you are facing problem of separating the remainder (if that what you want)
xor edx, edx
mov eax, 0xffffffff ; <- divide this
mov ecx, 6 ; by this
mov ebx, 100
mul ebx
div ecx
this is pretty simple :P
you all make it so complicated ... but what else should one expect from an assembly programming forum :lol:
i thought it was easy :P
Actually, here is an excellent idea:
"threshold" must be minimun 100 but can be any 24bit number
if (divisor <= threshold) {
xor edx, edx
mov eax, dividend
mov ecx, divisor
div ecx
mov eax, edx
imul eax, 100
xor edx, edx
div ecx
; now you need to get rid of 0
; If your end goal is to convert o ASCII then getiing rid of zero is best done prior to the conversion
}else{
mov eax, dividend
mov ecx, 100
mul ecx
mov ecx, divisor
div ecx
; now you need to separate the remainder and get rid of 0.
; If your end goal is to convert o ascii then separating(and zero elimination) is best done after conversion, probably
}
i think there is an API that will format it, actually
(2 functions used, as i remember, to convert from system time to formatted text)
but, i thought it was a good learning exercise, nonetheless
Quote from: qWord on January 07, 2013, 11:23:11 PM
It seems like that you mean the fractional part of a real number, when talking about the remainder.
So the question is: do you need the that for further calculation or just for printing? In the second case, simply make a floating point calculation and then use the CRT to format the number in a string buffer:
Thank you that Worked Great...
Quote from: qWord on January 06, 2013, 01:55:45 AM
you must use the FPU (or SSEx) to get floating point results:
LOCAl x:REAL8
fld FP8(9.0)
fdiv FP8(2.0) ; (commonly you would multiply by 0.5)
fstp x
fnc crt_printf,"%.8G\n",x
Now I understand This !!! :biggrin:
include \masm32\include\masm32rt.inc
division proto
.data
caption db "Division With Remainder Example", 0
Format db "%.9G",0
szBuffer db 32 dup(0)
.data?
x REAL8 ?
.code
Start:
invoke division
invoke MessageBox, 0, addr szBuffer, addr caption, MB_ICONQUESTION
invoke ExitProcess, 0
division Proc
;LOCAl x:REAL8 ; you can use local or Global
fld FP8(44.0)
fdiv FP8(7.0)
fstp x
invoke crt_sprintf,ADDR szBuffer,ADDR Format,x
ret
division endp
end Start
Quote from: dedndave on January 08, 2013, 04:38:42 AM
this is pretty simple :P
Nice refresh :t
I like that :icon_exclaim:
Quote from: hool on January 08, 2013, 03:15:15 AM
Quote from: dedndave on January 08, 2013, 01:55:56 AM
the easy way is to multiply the value by 100
or - divide the divisor by 100, if it is evenly divisable
or - some combination
You could refine that a bit to allow for a larger dividend . xor edx, edx
mov eax, 20 ; <- divide this (32bit)
mov ecx, 6 ; <- by this (24bit only)
div ecx ; eax =2
mov eax, edx
imul eax, 100
xor edx, edx
div ecx ; eax =33
. xor edx, edx
mov eax, 9 ; <- divide this (32bit)
mov ecx, 2 ; <- by this (24bit only)
div ecx ; eax =4
mov eax, edx
imul eax, 100
xor edx, edx
div ecx ; eax =50 (ALWAYS 2 digits)
; this is one way how to get rid of 0
mov edx, 0cccccccdh
mov ecx, eax
mul edx
shr edx, 3
mov eax, edx
imul eax, 10
cmp eax, ecx
cmovnz edx, ecx ; edx =5 (or =33 in previous example)
You can also go this way but if you run this example you are in big trouble because result of division will not fit into 32bit value. In addition, you are facing problem of separating the remainder (if that what you want)
xor edx, edx
mov eax, 0xffffffff ; <- divide this
mov ecx, 6 ; by this
mov ebx, 100
mul ebx
div ecx
Hi,
Thank you for the reply ....
Your first algo works great only for 20 divided by 6 ?? won't work for any other numbers
include \masm32\include\masm32rt.inc
; Only works with 20 / 6
division proto
.data
caption db "Division With Remainder Example", 0
Format db "%d.%d",0
var1 dd 20h ; binary value Dividned
var2 dd 6h ; binary value Divisor
buffer db 32 dup(0)
.data?
szRemainder dword ?
szRealNumber dword ?
.code
Start:
invoke division
invoke MessageBox, 0, addr buffer, addr caption, MB_ICONQUESTION + MB_OK
invoke ExitProcess, 0
division Proc
xor edx, edx
mov eax, var1 ; <- divide this (32bit)
mov ecx, var2 ; <- by this (24bit only)
div ecx ; eax =2
mov eax, edx ; move the Quotient to edx
imul eax, 100 ; 2 Decimal Places ,1000 is 3 etc....
xor edx, edx
div ecx ; eax =33
mov szRealNumber , edx
mov szRemainder,eax ; store the resulting Remainder in eax
invoke wsprintf, addr buffer, addr Format, edx, eax
ret
division endp
end Start
On the second example I get an error Here:
cmovnz edx, ecx ; edx =5 (or =33 in previous example)
Error:
division.asm(37) : error A2085: instruction or register not accepted in current CPU mode
include \masm32\include\masm32rt.inc
division proto
.data
caption db "Division With Remainder Example", 0
Format db "%d.%d",0
buffer db 32 dup(0)
.data?
szRemainder dword ?
szRealNumber dword ?
.code
Start:
invoke division
invoke MessageBox, 0, addr buffer, addr caption, MB_ICONQUESTION + MB_OK
invoke ExitProcess, 0
division Proc
xor edx, edx
mov eax, 9 ; <- divide this (32bit)
mov ecx, 2 ; <- by this (24bit only)
div ecx ; eax =4
mov eax, edx
imul eax, 100
xor edx, edx
div ecx ; eax =50 (ALWAYS 2 digits)
; this is one way how to get rid of 0
mov edx, 0cccccccdh
mov ecx, eax
mul edx
shr edx, 3
mov eax, edx
imul eax, 10
cmp eax, ecx
cmovnz edx, ecx ; edx =5 (or =33 in previous example)
mov szRealNumber , eax
mov szRemainder,edx ; store the resulting Remainder in eax
invoke wsprintf, addr buffer, addr Format, eax, edx
ret
division endp
end Start
3rd one is not working for me either ?
include \masm32\include\masm32rt.inc
division proto
.data
caption db "Division With Remainder Example", 0
Format db "%d.%d",0
buffer db 32 dup(0)
.data?
szRemainder dword ?
szRealNumber dword ?
.code
Start:
invoke division
invoke MessageBox, 0, addr buffer, addr caption, MB_ICONQUESTION + MB_OK
invoke ExitProcess, 0
division Proc
xor edx, edx
mov eax, 20 ; <- divide this
mov ecx, 6 ; by this
mov ebx, 100
mul ebx
div ecx
mov szRealNumber , eax
mov szRemainder,edx ; store the resulting Remainder in eax
invoke wsprintf, addr buffer, addr Format, eax, edx
ret
division endp
end Start
Am I doing something wrong?
Quote from: hool on January 08, 2013, 05:24:08 AM
Actually, here is an excellent idea:
"threshold" must be minimun 100 but can be any 24bit number
if (divisor <= threshold) {
xor edx, edx
mov eax, dividend
mov ecx, divisor
div ecx
mov eax, edx
imul eax, 100
xor edx, edx
div ecx
; now you need to get rid of 0
; If your end goal is to convert o ASCII then getiing rid of zero is best done prior to the conversion
}else{
mov eax, dividend
mov ecx, 100
mul ecx
mov ecx, divisor
div ecx
; now you need to separate the remainder and get rid of 0.
; If your end goal is to convert o ascii then separating(and zero elimination) is best done after conversion, probably
}
include \masm32\include\masm32rt.inc
division proto
.data
caption db "Division With Remainder Example", 0
Format db "%d.%d",0
dividend dd 20h ; binary value Dividned
divisor dd 6h ; binary value Divisor
threshold dd 100h ; threshold
.data?
buffer db 1024 dup(?)
szRemainder dword ?
szRealNumber dword ?
.code
Start:
invoke division
invoke MessageBox, 0, addr buffer, addr caption, MB_ICONQUESTION + MB_OK
invoke ExitProcess, 0
division Proc
; "threshold" must be minimun 100 but can be any 24bit number
.if eax<= threshold
xor edx, edx
mov eax, dividend
mov ecx, divisor
div ecx
mov eax, edx
imul eax, 100
xor edx, edx
div ecx
; now you need to get rid of 0
; If your end goal is to convert o ASCII then getiing rid of zero is best done prior to the conversion
.else
mov eax, dividend
mov ecx, 100
mul ecx
mov ecx, divisor
div ecx
; now you need to separate the remainder and get rid of 0.
; If your end goal is to convert o ascii then separating(and zero elimination) is best done after conversion, probably
.endif
mov szRealNumber , eax
mov szRemainder,ebx ; store the resulting Remainder in eax
invoke wsprintf, addr buffer, addr Format, eax, ebx
ret
division endp
end Start
I am sorry I don't follow you here...can you use my above example and put it in ?
Thank you
mov eax, 200
mov ecx, 100
mul ecx
mov ecx, 31
div ecx
mov esi, eax
mov edi, eax
invoke wsprintf, addr buffer, addr Format, esi, edi
invoke MessageBox, 0,addr buffer, 0, MB_ICONQUESTION+MB_OK
Now you have to explain why you see "645.645"
mov eax, 0xffffffff
mov ecx, 100
mul ecx
mov ecx, 31
div ecx
mov esi, eax
mov edi, eax
invoke wsprintf, addr buffer, addr Format, esi, edi
invoke MessageBox, 0,addr buffer, 0, MB_ICONQUESTION+MB_OK
Now you have to explain why it crashes
xor edx, edx
mov eax, 200
mov ecx, 31
div ecx
mov esi, eax
mov eax, edx
imul eax, 100
xor edx, edx
div ecx
mov edi, eax
invoke wsprintf, buffer, Format1, esi, edi
invoke MessageBox, 0,addr buffer, 0, MB_ICONQUESTION+MB_OK
Now you have to explain why you see "6.45"
And only after all that do something more complex
Hello,
Quote from: hool on January 08, 2013, 11:15:03 PM
mov eax, 200
mov ecx, 100
mul ecx
mov ecx, 31
div ecx
mov esi, eax
mov edi, eax
invoke wsprintf, addr buffer, addr Format, esi, edi
invoke MessageBox, 0,addr buffer, 0, MB_ICONQUESTION+MB_OK
Now you have to explain why you see "645.645"
mov eax, 0xffffffff
mov ecx, 100
mul ecx
mov ecx, 31
div ecx
mov esi, eax
mov edi, eax
invoke wsprintf, addr buffer, addr Format, esi, edi
invoke MessageBox, 0,addr buffer, 0, MB_ICONQUESTION+MB_OK
Now you have to explain why it crashes
xor edx, edx
mov eax, 200
mov ecx, 31
div ecx
mov esi, eax
mov eax, edx
imul eax, 100
xor edx, edx
div ecx
mov edi, eax
invoke wsprintf, buffer, Format1, esi, edi
invoke MessageBox, 0,addr buffer, 0, MB_ICONQUESTION+MB_OK
Now you have to explain why you see "6.45"
And only after all that do something more complex
For the record I asked , about the error I was getting with
cmovnz edx, ecx ; edx =5 (or =33 in previous example)
division.asm(37) : error A2085: instruction or register not accepted in current CPU mode
I am not familiar with cmovnz instruction ... Not about
0xffffffff
Also I still Don't get were you are Going with this?
"threshold" must be minimun 100 but can be any 24bit number
if (divisor <= threshold) {
xor edx, edx
mov eax, dividend
mov ecx, divisor
div ecx
mov eax, edx
imul eax, 100
xor edx, edx
div ecx
; now you need to get rid of 0
; If your end goal is to convert o ASCII then getiing rid of zero is best done prior to the conversion
}else{
mov eax, dividend
mov ecx, 100
mul ecx
mov ecx, divisor
div ecx
; now you need to separate the remainder and get rid of 0.
; If your end goal is to convert o ascii then separating(and zero elimination) is best done after conversion, probably
}
But to answer your question best I can
Q 1. Now you have to explain why you see "645.645"
A 1. you are dividing 200 by 31 and moving the Quotient to eax twice without dividing it by 100
Q 2.Now you have to explain why it crashes
A 2. 0xffffffff or in MASM 0FFFFFFFFh Alternative representation -1 as error indicator flag , also as a max unsigned Variable ( the larger of the 2 numbers ) So In this case I assume you meant it o represent a number larger than 31.
Q 3.Now you have to explain why you see "6.45"
A 3. you are properly dividing now and moving the Quotient and remainder (to 2 decimal places) to proper registers to show it
esi = Quotient and edi = remainder
:(
division.asm(37) : error A2085: instruction or register not accepted in current CPU mode
you need to define the "cpu model" at least
.686
masm32rt.inc defined it as .486
@Dubby
Thanks !!!! :biggrin:
I never encountered any thing where that made a difference before
Experience says a lot ! Thank you again Dubby :biggrin: