flat assembler
Message board for the users of flat assembler.

 Index > Windows > Dividing negative numbers
Author
 Thread
lem

Joined: 16 Sep 2013
Posts: 4
lem 20 Sep 2013, 13:32
Code:
```format PE console
entry start

include 'win32a.inc'

;=============================
section '.rdata' data readable
;=============================
pi db 'Liczba PI wynosi: %d.%d', 10, 0
;==============================
section '.text' code executable
;==============================
start:
push ebp
mov ebp, esp
mov eax, 4
mov [ebp-8], eax        ;znak

mov eax,  1
mov [ebp-16], eax       ;mianownik

mov eax, 2
mov [ebp-24], eax       ;licznik

mov eax, 0
mov [ebp-32], eax       ;wartosc dziesietna pi

mov eax, 0
mov [ebp-40], eax

petla:

;       --------------------------
;       dzielenie znaku przez mianownik
mov eax, [ebp-8]
mov ebx, [ebp-16]

xor edx, edx
idiv ebx

add [ebp-32], eax
add [ebp-40], edx
;       --------------------------
;       zwiekszenie mianownika o 2
mov eax, [ebp-16]
add eax, 2
mov [ebp-16], eax
;       --------------------------
;       negacja znaku
mov eax, [ebp-8]
neg eax
mov [ebp-8], eax
;       --------------------------
;       dekrementacja licznika
mov eax, [ebp-24]
dec eax

mov [ebp-24], eax
jnz petla

crap:
mov eax, [ebp-32]
mov ebx, [ebp-40]
push ebx                ;przekazanie ebx do printf
push eax                ;przekazanie eax do printf
push pi                 ;przekazanie string'a do printf
call [printf]
ccall [getchar]

koniec:
stdcall [ExitProcess], 0
;====================================
section '.idata' import data readable
;====================================
library kernel32, 'kernel32.dll', \
msvcrt,   'msvcrt.dll'
import kernel32, ExitProcess, 'ExitProcess'
import msvcrt, printf, 'printf', getchar, '_fgetchar'
```

Hi,
I've got this code, and it should use Leibniz's formula to print out PI number. However, I have no clue why during the second go through the loop everything what i receive in EAX or EDX is simply crap which does not match at all with my calculations. Any clue what i'm doing wrong?

here's cpp version
Code:
```#include <iostream>

using namespace std;

int main()
{
int i;
cout << "Number of iterations: ";
cin >> i;
long int denominator = 1;
long double pi = 0;
int sign = 4;

for(long long int j = 0; j < i; j++)
{
pi += (long double) sign / (long double) denominator;
sign = -sign;
denominator += 2;
}
cout.precision(10);
cout << "Liczba Pi w przyblizeniu wynosi: ";
cout << pi;
return 0;
}
```
20 Sep 2013, 13:32
AsmGuru62

Joined: 28 Jan 2004
Posts: 1497
Location: Toronto, Canada
AsmGuru62 20 Sep 2013, 13:49
I think you must use FPU to get that correctly done.
This does not look like integer division/addition:
Code:
```pi += (long double) sign / (long double) denominator;
```
20 Sep 2013, 13:49
lem

Joined: 16 Sep 2013
Posts: 4
lem 20 Sep 2013, 13:57
Yeah, so idiv does not does that, does it?
Do you have ideas how to actually use FP in here?
20 Sep 2013, 13:57
AsmGuru62

Joined: 28 Jan 2004
Posts: 1497
Location: Toronto, Canada
AsmGuru62 20 Sep 2013, 15:14
IDIV will divide EDX:EAX as an integer value, so you get the integer remainder and integer result, like if you divide 10 by 3 you get 3 (RESULT) and 1 (REMAINDER) - all integer.

I will try to make a code sample for FPU.
20 Sep 2013, 15:14
lem

Joined: 16 Sep 2013
Posts: 4
lem 20 Sep 2013, 15:16
Wow, thanks, i just did not know that idiv works with integers only. Looking forward for that sample and in meantime i'll read this
http://www.website.masmforum.com/tutorials/fptute/index.html
which you've posted somewhere else in the past.
20 Sep 2013, 15:16
AsmGuru62

Joined: 28 Jan 2004
Posts: 1497
Location: Toronto, Canada
AsmGuru62 20 Sep 2013, 16:07
Here is some working code.
I did not print anything, so you'll have to stop in debugger and check the results.
Code:
```; ---------------------------------------------------------------------------
; FILE: GetPI.Asm
; DATE: September 20, 2013
; ---------------------------------------------------------------------------

format  PE GUI 4.0
entry   start
stack   4000h, 4000h

include 'Win32W.Inc'
; {INSMODDEF} Module Definitions inserted immediately before this line

; ---------------------------------------------------------------------------
section '.data' data readable writeable

double_PI1      dt 0.0
double_PI2      dt 0.0

; ---------------------------------------------------------------------------
section '.code' code readable executable

; {INSMODIMPL} Module Implementations inserted immediately before this line

; ---------------------------------------------------------------------------
virtual at 0
loc1:
.Long_Sign         dd ?
.Long_Denominator  dd ?
.CurrentPi         dt ?  ; 10 bytes DOUBLE
.Padding           rb 2  ; To align stack on DWORD
.size = \$
end virtual

align 16
GetPI_Entry:
; ---------------------------------------------------------------------------
; INPUT:
;   ECX = # of iterations
;   EDI = address of a DOUBLE value where to put the result (calculated PI)
; ---------------------------------------------------------------------------
;
; Allocate local variables
;
sub       esp, loc1.size
mov       esi, esp
;
; Prepare locals
;
push      1
pop       eax
mov       [esi + loc1.Long_Denominator], eax   ; Denominator = 1

add       eax, 3
mov       [esi + loc1.Long_Sign], eax          ; Sign = 4

fldz
fstp      [esi + loc1.CurrentPi]               ; Pi = 0.0
;
; Loop the # of iterations in ECX
;
.iteration:
fild      [esi + loc1.Long_Sign]
fidiv     [esi + loc1.Long_Denominator]
fld       [esi + loc1.CurrentPi]
faddp
fstp      [esi + loc1.CurrentPi]

neg       [esi + loc1.Long_Sign]
add       [esi + loc1.Long_Denominator], 2

loop      .iteration
;
; Store the result
;
fld       [esi + loc1.CurrentPi]
fstp      tword [edi]
;
; Release locals and exit
;
add       esp, loc1.size
ret

; ----------------------------------------------
; C++ Equivalent for ABOVE ^^^ (just the calculations)
; ----------------------------------------------
;int main()
;{
;    int i;
;    cout << "Number of iterations: ";
;    cin >> i;
;    long int denominator = 1;
;    long double pi = 0;
;    int sign = 4;
;
;    for(long long int j = 0; j < i; j++)
;    {
;        pi += (long double) sign / (long double) denominator;
;        sign = -sign;
;        denominator += 2;
;    }
;    cout.precision(10);
;    cout << "Liczba Pi w przyblizeniu wynosi: ";
;    cout << pi;
;    return 0;
;}

; ---------------------------------------------------------------------------
; PROGRAM ENTRY POINT
; ---------------------------------------------------------------------------
align 16
start:
;
; Try it twice with different # of iterations
;
mov       edi, double_PI1
mov       ecx, 256
call      GetPI_Entry

mov       edi, double_PI2
mov       ecx, 4096
call      GetPI_Entry
;
; Now load them into FPU and compare with 'real' Pi
;
fld       [double_PI2]
fld       [double_PI1]
fldpi
;
; Stop in debugger and look into FPU registers:
;
; ST0 = Pi calculated by FPU
; ST1 = Pi calculated by 256 iterations
; ST2 = Pi calculated by 4096 iterations
;
int3
;
; Get back to Windows
;
invoke    ExitProcess, 0

; ---------------------------------------------------------------------------
section '.idata' import data readable writeable

library kernel32,'KERNEL32.DLL',user32,'USER32.DLL',gdi32,'GDI32.DLL'

include 'API\Kernel32.Inc'
include 'API\User32.Inc'
include 'API\Gdi32.Inc'
```
20 Sep 2013, 16:07
lem

Joined: 16 Sep 2013
Posts: 4
lem 20 Sep 2013, 16:19
Yup, I've checked them and they are really good. Thanks a lot, that's a really nice code you did there and it's definitely more advanced than mine crap. However with being more advanced it looks simpler. Anyways, thanks a lot for your work : )
20 Sep 2013, 16:19
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainTutorials and ExamplesDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsOS ConstructionIDE DevelopmentProjects and IdeasNon-x86 architecturesHigh Level LanguagesProgramming Language DesignCompiler Internals Other----------------FeedbackHeapTest Area

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum

Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.