flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
idle 23 Jan 2011, 06:55
hi
this is a small revision Tomasz, i think break if condition, and break stopping macro execution, would make a big deal ![]() this... Code: ;divisor = 0'000'000'010 mov eax,dividend mov edx,$CCCC'CCCD ;normalized reciprocal(0.099999999860301613 * 2^03) mul edx ;multiply id est divide ...is generated by this Code: ; the macro generates constants to replace div by mul ; having questions, mail me to edemko@rambler.ru, or find me at www.board.flatassembler.net ; examples: rcp32 0 ; rcp32 1 ; rcp32 2 ; rcp32 10 ; rcp32 60 ; rcp32 100 ; rcp32 60*60 ; ... macro rcp32 divisor*{ virtual at 0 local dvs dvs = divisor if dvs shr 32 <> 0 display 13, 10, 'divisor must be a 32bit value' err end if if dvs < 2 display 13, 10, 'division by ', dvs + '0', ' is easy' err end if display 13, 10, ' ;divisor = ',\ dvs / 1'000'000'000 + '0',\ '''',\ (dvs / 0'100'000'000) mod 10 + '0',\ (dvs / 0'010'000'000) mod 10 + '0',\ (dvs / 0'001'000'000) mod 10 + '0',\ '''',\ (dvs / 0'000'100'000) mod 10 + '0',\ (dvs / 0'000'010'000) mod 10 + '0',\ (dvs / 0'000'001'000) mod 10 + '0',\ '''',\ (dvs / 0'000'000'100) mod 10 + '0',\ (dvs / 0'000'000'010) mod 10 + '0',\ dvs mod 10 + '0' repeat 31 if dvs = 1 shl % display 13, 10, 'mov eax,dividend',\ 13, 10, 'shr eax,', % / 10 + '0', % mod 10 + '0', ' ;divisor is power of 2 |
|||
![]() |
|
idle 31 Jan 2011, 06:30
this is v3:
- new hex macro - fraction macro supports 64 bit fractions - rounding corrected - set LANG equ ENU to switch from RUS, that's the reason i did not put code directly
|
|||||||||||
![]() |
|
idle 01 Feb 2011, 10:59
this is v4:
- new hex macro - rounding corrected, staying experimental - english language only, i'm sorry, let me know and i'll write russian one - macro supports check-code creation main file: Code: ;show_hex <13,10,'$'>, 00, 00, ';',\ ; <13,10,'$'>, 01, 01, ';',\ ; <13,10,'$'>, 02, 02, ';',\ ; <13,10,'$'>, 03, 03, ';',\ ; <13,10,'$'>, 04, 04, ';',\ ; <13,10,'$'>, 05, 05, ';',\ ; <13,10,'$'>, 06, 06, ';',\ ; <13,10,'$'>, 07, 07, ';',\ ; <13,10,'$'>, 08, 08, ';',\ ; <13,10,'$'>, 09, 09, ';',\ ; <13,10,'$'>, 10, 10, ';',\ ; <13,10,'$'>, 11, 11, ';',\ ; <13,10,'$'>, 12, 12, ';',\ ; <13,10,'$'>, 13, 13, ';',\ ; <13,10,'$'>, 14, 14, ';',\ ; <13,10,'$'>, 15, 15, ';',\ ; <13,10,'$'>, 16, 16, ';',\ ; <13,10,'$'>, 17, 17, ';' ; ;repeat 18 ; show_hex <13,10,'$'>, %-1, ';' ;end repeat macro show_hex [intro, val, count, outro]{ common local c, v, d forward display intro c = count if c > 0 & c < 17 v = val while c > 0 c = c - 1 d = v shr (c * 4) and 1111b display d + '0' + d/10*7 if c <> 0 & c mod 4 = 0 display '''' end if end while end if display outro } ;show_frac <13,10,'2^-1 : '>, $8000'0000'0000'0000, ';',\ ; <13,10,'2^-2 : '>, $4000'0000'0000'0000, ';',\ ; <13,10,'2^-1 + 2^-2: '>, $c000'0000'0000'0000, ';' ; ;repeat 64 ; show_frac <13,10>, 1 shl (%-1), '' ;end repeat macro show_frac [intro, val, outro]{ common local a, b forward display intro, '0.' a = (val) and $ffff'ffff b = (val) shr 32 repeat 18 a = a * 10 b = b * 10 + a shr 32 display b shr 32 + '0' a = a and $ffff'ffff b = b and $ffff'ffff if % = 18 display outro else if % mod 3 = 0 display '''' end if end repeat } ;repeat 17 ; display 13,10 ; rcp32 %-1 ;end repeat ; ;repeat 17 ; display 13,10 ; rcp32 %-1, :) ;end repeat macro rcp32 val, check{ local dvs dvs = (val) and $ffff'ffff repeat 1 if dvs < 2 display 13, 10, ':) can you not divide by ', dvs + '0' break end if local dvd, quo, cnt, cnt? dvd = 1 quo = 0 cnt = 0 cnt? = 1 repeat 64 dvd = dvd shl 1 quo = quo shl 1 if dvd < dvs if cnt? = 1 cnt = cnt + 1 end if else cnt? = 0 dvd = dvd - dvs quo = quo + 1 end if end repeat show_hex <13, 10, '; divisor[$1f..$00] = $'> , dvs, 8, '',\ <13, 10, '; 1/divisor[$1f..$00] = $0.'>, quo, 16, '' show_frac '(', quo, ')' repeat 31 if dvs = 1 shl % show_hex <13, 10, 'code: shr eax,$'>, %, 2, ' ; divisor is this power of two' dvs = 0 break end if end repeat if dvs = 0 break end if quo = quo shr (32-cnt-1) if quo and 1 = 1 quo = quo + 10b else quo = quo or 10b end if quo = quo shr 1 show_hex <13, 10, 'code: mov edx,$'>, quo, 8, ' ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$', '', cnt, 2, '), and rounded',\ <13, 10, ' mul edx ; id est div :)'>, , 0, '',\ <13, 10, ' shr edx,$'>, cnt, 2, ' ; compensate quotient' if ~ check eq show_hex <13,10,'; use this code to check rcp32 over',\ 13,10,' call check',\ 13,10,' jne mail_edemko@rambler.ru_about_rounding_error',\ 13,10,' invoke MessageBoxA,0,''rcp32 returned ok'',0,0',\ 13,10,' invoke ExitProcess,0',\ 13,10,'mail_edemko@rambler.ru_about_rounding_error:',\ 13,10,' hlt',\ 13,10,'check: mov esi,$'>,dvs,8,<\ 13,10,' or ecx,-1',\ 13,10,' .loop:xor edx,edx',\ 13,10,' mov eax,ecx',\ 13,10,' div esi',\ 13,10,' mov ebx,eax',\ 13,10,' mov eax,$'>,'',quo,8,<\ 13,10,' mul ecx',\ 13,10,' shr edx,$'>,'',cnt,2,<\ 13,10,' cmp edx,ebx',\ 13,10,' loope .loop',\ 13,10,' ret'> end if end repeat} this... Code: repeat 17 display 13,10 rcp32 %-1 end repeat ...creates this: Code: :) can you not divide by 0 :) can you not divide by 1 ; divisor[$1f..$00] = $0000'0002 ; 1/divisor[$1f..$00] = $0.8000'0000'0000'0000(0.500'000'000'000'000'000) code: shr eax,$01 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0003 ; 1/divisor[$1f..$00] = $0.5555'5555'5555'5555(0.333'333'333'333'333'333) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$01), and rounded mul edx ; id est div :) shr edx,$01 ; compensate quotient ; divisor[$1f..$00] = $0000'0004 ; 1/divisor[$1f..$00] = $0.4000'0000'0000'0000(0.250'000'000'000'000'000) code: shr eax,$02 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0005 ; 1/divisor[$1f..$00] = $0.3333'3333'3333'3333(0.199'999'999'999'999'999) code: mov edx,$CCCC'CCCD ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; divisor[$1f..$00] = $0000'0006 ; 1/divisor[$1f..$00] = $0.2AAA'AAAA'AAAA'AAAA(0.166'666'666'666'666'666) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; divisor[$1f..$00] = $0000'0007 ; 1/divisor[$1f..$00] = $0.2492'4924'9249'2492(0.142'857'142'857'142'857) code: mov edx,$9249'2493 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; divisor[$1f..$00] = $0000'0008 ; 1/divisor[$1f..$00] = $0.2000'0000'0000'0000(0.125'000'000'000'000'000) code: shr eax,$03 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0009 ; 1/divisor[$1f..$00] = $0.1C71'C71C'71C7'1C71(0.111'111'111'111'111'111) code: mov edx,$E38E'38E4 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000A ; 1/divisor[$1f..$00] = $0.1999'9999'9999'9999(0.099'999'999'999'999'999) code: mov edx,$CCCC'CCCD ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000B ; 1/divisor[$1f..$00] = $0.1745'D174'5D17'45D1(0.090'909'090'909'090'909) code: mov edx,$BA2E'8BA3 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000C ; 1/divisor[$1f..$00] = $0.1555'5555'5555'5555(0.083'333'333'333'333'333) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000D ; 1/divisor[$1f..$00] = $0.13B1'3B13'B13B'13B1(0.076'923'076'923'076'923) code: mov edx,$9D89'D89E ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000E ; 1/divisor[$1f..$00] = $0.1249'2492'4924'9249(0.071'428'571'428'571'428) code: mov edx,$9249'2493 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'000F ; 1/divisor[$1f..$00] = $0.1111'1111'1111'1111(0.066'666'666'666'666'666) code: mov edx,$8888'8889 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; divisor[$1f..$00] = $0000'0010 ; 1/divisor[$1f..$00] = $0.1000'0000'0000'0000(0.062'500'000'000'000'000) code: shr eax,$04 ; divisor is this power of two this... Code: repeat 17 display 13,10 rcp32 %-1, :) end repeat ...creates this: Code: :) can you not divide by 0 :) can you not divide by 1 ; divisor[$1f..$00] = $0000'0002 ; 1/divisor[$1f..$00] = $0.8000'0000'0000'0000(0.500'000'000'000'000'000) code: shr eax,$01 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0003 ; 1/divisor[$1f..$00] = $0.5555'5555'5555'5555(0.333'333'333'333'333'333) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$01), and rounded mul edx ; id est div :) shr edx,$01 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'0003 or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$AAAA'AAAB mul ecx shr edx,$01 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'0004 ; 1/divisor[$1f..$00] = $0.4000'0000'0000'0000(0.250'000'000'000'000'000) code: shr eax,$02 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0005 ; 1/divisor[$1f..$00] = $0.3333'3333'3333'3333(0.199'999'999'999'999'999) code: mov edx,$CCCC'CCCD ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'0005 or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$CCCC'CCCD mul ecx shr edx,$02 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'0006 ; 1/divisor[$1f..$00] = $0.2AAA'AAAA'AAAA'AAAA(0.166'666'666'666'666'666) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'0006 or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$AAAA'AAAB mul ecx shr edx,$02 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'0007 ; 1/divisor[$1f..$00] = $0.2492'4924'9249'2492(0.142'857'142'857'142'857) code: mov edx,$9249'2493 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$02), and rounded mul edx ; id est div :) shr edx,$02 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'0007 or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$9249'2493 mul ecx shr edx,$02 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'0008 ; 1/divisor[$1f..$00] = $0.2000'0000'0000'0000(0.125'000'000'000'000'000) code: shr eax,$03 ; divisor is this power of two ; divisor[$1f..$00] = $0000'0009 ; 1/divisor[$1f..$00] = $0.1C71'C71C'71C7'1C71(0.111'111'111'111'111'111) code: mov edx,$E38E'38E4 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'0009 or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$E38E'38E4 mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000A ; 1/divisor[$1f..$00] = $0.1999'9999'9999'9999(0.099'999'999'999'999'999) code: mov edx,$CCCC'CCCD ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000A or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$CCCC'CCCD mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000B ; 1/divisor[$1f..$00] = $0.1745'D174'5D17'45D1(0.090'909'090'909'090'909) code: mov edx,$BA2E'8BA3 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000B or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$BA2E'8BA3 mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000C ; 1/divisor[$1f..$00] = $0.1555'5555'5555'5555(0.083'333'333'333'333'333) code: mov edx,$AAAA'AAAB ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000C or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$AAAA'AAAB mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000D ; 1/divisor[$1f..$00] = $0.13B1'3B13'B13B'13B1(0.076'923'076'923'076'923) code: mov edx,$9D89'D89E ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000D or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$9D89'D89E mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000E ; 1/divisor[$1f..$00] = $0.1249'2492'4924'9249(0.071'428'571'428'571'428) code: mov edx,$9249'2493 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000E or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$9249'2493 mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'000F ; 1/divisor[$1f..$00] = $0.1111'1111'1111'1111(0.066'666'666'666'666'666) code: mov edx,$8888'8889 ; 1/divisor[$1f..$00], converted to 32 bits(shr $20-$03), and rounded mul edx ; id est div :) shr edx,$03 ; compensate quotient ; use this code to check rcp32 over call check jne mail_edemko@rambler.ru_about_rounding_error invoke MessageBoxA,0,'rcp32 returned ok',0,0 invoke ExitProcess,0 mail_edemko@rambler.ru_about_rounding_error: hlt check: mov esi,$0000'000F or ecx,-1 .loop:xor edx,edx mov eax,ecx div esi mov ebx,eax mov eax,$8888'8889 mul ecx shr edx,$03 cmp edx,ebx loope .loop ret ; divisor[$1f..$00] = $0000'0010 ; 1/divisor[$1f..$00] = $0.1000'0000'0000'0000(0.062'500'000'000'000'000) code: shr eax,$04 ; divisor is this power of two |
|||
![]() |
|
idle 01 Oct 2011, 09:08
Code: 2011_??_?? english ~~~~~~~ This file tells how to divide 1 by integer. 1/0 & 1/1 are easy. First we should understand 1/123(e.g.) in decimal to use the principle in binary then. Imagine amount of liquid(e.g. juice). Imagine a vessel of 123 capacity(e.g. a glass). Our task is to fill the vessel with liquid as many times as possible until liquid ends. In other words, you drink juice *glass after a glass* until the juice is drunk. In other words, *each glass* glass count increases, juice decreases. In other words, *each division* quotient increases, dividend decreases. 1 is a unit, consisting of smaller ones: mili- micro- nano- etc-. This is scaling, and we are just storing quotient of mili- micro- nano- etc- size. Ok, let us drink that juice ![]() |
|||
![]() |
|
idle 03 Oct 2011, 18:35
i misused the two terms
i beg your pardon if it happens again (BSR divisor)[+1] the answer is. mov edx,65'535 ;arbitrary dividend mul edx ;0.1 * dividend english & slavic(ukrainian) |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.