News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

count with overflow

Started by vivendi, October 04, 2006, 12:32:24 PM

Previous topic - Next topic

vivendi

Hello, i've done a few assignments now, which went pretty good (thanks to you guys), but im
having some dificulties with this one, i have to show the sum of large numbers which create an overflow.

These are the numbers:
2000000001,2000000002,2000000003,2000000004,2000000005

I think these are big enough to create an overflow, but what i have to do now is to do something
so that it wont create an overflow, but just calculate the sum of those numbers somehow...

I dont know how to catch the overflow, so that it wont display a weird number, so hopefully you guys
can help me a bit with this.

This is the code i have right now:


.386
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

.data
  nummers dd 2000000001,2000000002,2000000003,2000000004,2000000005
  message db "Totaal is %d",0

.data?
  buffer db 100 dup(?)

.code

start:
  xor eax,eax
  mov ecx, 5
  mov edx, OFFSET nummers

Count:
  add eax, DWORD PTR [edx]
  add edx, 4

  dec ecx
  jnz Count

  invoke wsprintf,ADDR buffer,ADDR message,eax
  invoke StdOut, ADDR buffer
  invoke ExitProcess,0

END start


*edit*

Just wanted to let you know that i found the ADC instruction, i guess thats the one i need, so im gonna try it with that instruction to see if i succeed.

Shantanu Gadgil

ADC is the correct instruction you have found!

Now...how to represent a 64 bit number (32 x 2). Hmmmm...I will leave that upto you!  :bg :bdg :bg

Regards,
Shantanu
To ret is human, to jmp divine!

Ratch

vivendi,

     Well, let's see.  The first thing we have to do is get you squared away on what is an overflow and what is a carry.  Forget about overflow unless you are working with signed integers.  An unsigned integer sets the CARRY FLAG if the value is greater than can be contained in a BYTE, WORD, or DWORD.  A 32-bit DWORD can represent a unsigned value of around 4 billion, so three of your example numbers will cause a CARRY FLAG to be set.  You can test it by coding a JC (Jump Carry)  instruction.  For what you are doing, you would NOT use the ADC instruction, which adds a one to the sum if the carry flag is set.  Just use the ADD instruction and test for the CF after each summation.  I would advise you to read the link below so you understand what are the relationships of the CF and OF flags with numeric operations.  Ratch

http://www.masm32.com/board/index.php?topic=2923.0

vivendi

Thanks for pointing out what to do, i will read the page from the link tommorrow, its getting pretty late now.
But ill let you know if i succeed or not :)

vivendi

I've been searching for some more information about this. but i didnt find anything that could help me.
I used the JC instruction to see if there's a carry, im not sure if its right what im doing, but it jumps on a certain point to the label.
Then it says "Carry is set" in console and outputs the sum of those numbers as '14'.

Im not sure what to do with the JC command and what to do after that, all i've seen on google is that you can jump to a new location, but not what to do after that. Could you please help me out with this.

My code:

.data
    numbers dd 2000000001,2000000002,2000000003,2000000004,2000000005
    message db "Totaal is %d",0
    testmsg    db "Carry is set",10,13


.data?
    buffer  db 100 dup(?)


.code

start:

    xor     eax,eax
    mov     edx,OFFSET numbers
    mov     ecx,5
Count:
    add     eax,DWORD PTR [edx]
    add     edx,4
    jc      GotoCarry   ;is there a carry??
                               
    dec     ecx
    jnz     Count

GotoCarry:
    invoke  StdOut,ADDR testmsg

    invoke  wsprintf,ADDR buffer,ADDR message,eax
    invoke  StdOut,ADDR buffer
    invoke  ExitProcess,0       

END start

Shantanu Gadgil

Hi vivendi,
JC (Jump if Carry) can be used for taking a decision.

What I understood from your previous post was that you wanted to add two numbers (quite large) whose addition would be more than than the register size (32 bits) and then how would you either store it or work with it in some way. Am I right so far?

If this is what you _do_ want, heres the algorithm:
*) there would be two entities low_dword and high_dword
*) keep doing the following two steps in a loop:
   add whatever number to low_dword
   add with carry to high_dword

At the end you would get some value in the high_dword which is actually a multiple of 4 GB and the low_dword value would be as is.
so the total number is (high_dword * 4GB + low_dword)

Hope that helps,

Regards,
Shantanu
To ret is human, to jmp divine!

dsouza123


start:
    xor     eax,eax
    xor     edx,edx
    xor     ecx,ecx
   
Count:
    add     eax, [numbers + ecx*4]
    adc     edx,0
    inc     ecx
    cmp     ecx,5
    jb      Count

    mov     total+0, eax   ; eax has the lower 32 bits of the total
    mov     total+4, edx   ; edx has the higher

    or      edx,edx   ; if edx != 0
    jz      Past
    ; a carry was done at some point during the additions
    ;
Past:


MichaelW

vivendi,

The convention is that called functions do not preserve eax, ecx, or edx, so you need to preserve eax around the call to StdOut.

...
push eax
invoke  StdOut,ADDR testmsg
pop eax
invoke  wsprintf,ADDR buffer,ADDR message,eax
...


Also, the output buffer for wsprintf is not guaranteed to be null terminated (and it was not in my test of your code), so you should start out with the buffer initialized to zeros.

.data
...
buffer db 100 dup(0)
...


MSDN: wsprintf
eschew obfuscation

Ratch

vivendi,

     Look at the snippet of your code.
Count:
    add     eax,DWORD PTR [edx]
    add     edx,4
    jc      GotoCarry   ;is there a carry??
                               
    dec     ecx
    jnz     Count

GotoCarry:
    invoke  StdOut,ADDR testmsg


     The add eax,DWORD PTR [edx] instruction will set or clear the CF.  The next instruction should be the JC instruction.  The add  edx,4 instruction will clear the CF until the loop count is past 4 billion.  There should not be a JC instruction after the loop test.  You have both the loop fall through and the JC going to the same place.  What good is that?  You should have the JC going to some error routine and the successful addition going somewhere else.  Ratch