News:

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

help?

Started by seymour_glass, March 17, 2006, 12:50:08 AM

Previous topic - Next topic

seymour_glass

I am fairly new to MASM, although i have slight knowledge in c++, vb....c#.....and....i need some help.

Ive got a program trying to find the first one hundred prime numbers, and output them in rows of 5.  my code is flawed and i need some help figuring out why.  it outputs the the numbers  2, 3, 4....and the rest are zeros.   It should jump out of the test on 4(because it is not prime) and increment it.  yet it somehow is displaying 4...and then i guessing some sort of division by zero (witn no error).  finally, it does not output 5 per line....no idea.....

i will attach it, in case anyone feels like giving me some advice......

Dennis
(also...I;m sure this isn't the most efficient code....help appreciated, but im not all that concerned about that right now.......

[attachment deleted by admin]

seymour_glass

ok, i figured out part of it i think....but now its kinda freezing (or pausing). I dont think that my loops were all connected the way they should have been. Im attaching the new file

[attachment deleted by admin]

MichaelW

You would be more likely to get help if you would post your code instead of forcing us to download and extract it, and if it were more reasonably formatted (so it would be easier to read).

I don't know about io.h or how output works, but it seems strange that your strings have no terminator.

What is the purpose of the trailing cr. Lf, 0 on this:

nbrArray  DWORD maxNbrs DUP (?), cr, Lf, 0

You could avoid having to initialize the first two primes at run time by defining your array as:

nbrArray  DWORD 2, 3, 98 DUP (?)

This instruction:

idiv ebx

Is dividing EAX (the candidate) by the value in EBX, which is the address of an array element. You need to divide EAX by the contents of the address (I used an unsigned divide only because it makes more sense here):

div DWORD PTR[ebx]

The code has problems beyond this. If your logic were cleaner and easier to understand you would be more likely to find the problems.

Also, I doubt that the value of 5 for the number of columns is arbitrary. With the normal 80-column console, if you follow each number with two tab characters (ASCII code 9) then the output will wrap after 5 numbers, achieving the desired output format without any looping.


eschew obfuscation

Tedd

* fatal mistake:
  lea ebx,nbrArray      ;*** ebx = the address of nbrArray
  ;test current prime
  mov eax,candidate
nextPrime:
  cdq
  idiv ebx      ;and get next prime if prime/candidate

You don't want to idiv with ebx, as this means "candidate divided_by the_address_of_the_array"
What you actually want to do is divide by the number IN the array, which means the dword at the address pointed to by ebx (not the value of ebx itself.)
Try "idiv DWORD PTR [ebx]" :wink

* another unfortunate mistake:
    mov   eax, candidate
  nextPrime:
    .
    ;do the division
    .
    jmp   nextPrime

What is the value of eax after the first loop? What should it be?
This is similar to a few more problems in this area, with the different parts of the loops -- whilePrimeCount, nextPrime, incCandidate, storePrime
Make sure you understand what should happen in each case, and make sure all indexes, values, and the candidate are the correct value ready for the next loop

* calls to functions (eg. output, dtoa) will probably not save the values of your registers (especially ecx) so you may want to save those values before you call the functions (see "push" and "pop")
  {I could be wrong, and these functions have been made so they do save your registers, but without the code I can't tell}

* does the "output" function require that the string you want to print ends with a zero? (because none of yours do -- explain, endNumLabel, newLine)

* no comment :green
  jmp   nextPrime2
nextPrime2:


* there may be one or two other little things, but you should see them once the rest is working
No snowflake in an avalanche feels responsible.

Shantanu Gadgil

does(doesn't :toothy) the name of the zip file give any indication as to why the question is being asked?  :green2 :green2 :green2
To ret is human, to jmp divine!

Tedd

Which is why I gave instructions, rather than full corrections :P

(I see no problem helping with homework as long as effort has been made.)
No snowflake in an avalanche feels responsible.

seymour_glass

thank you all,

my teacher finally sat down with me and i finally got it figured out this afternoon.  I now see that if it were clearer, I could have picked them out myself.  That is something i would like to refine as this is my first architecture class, and I think it would be advantageous to be able to lay it out less messily.

As to the 0's thing...I was under the impression that I reallly only want that when i want it to stop there.  Example....

newLine  cr, Lf 

It seems that i wouldnt need that null zero unless i need the instruction to stop there....am i confused?  Although I probaby did need it to.....Just to get that out there before I get jumped...lol

As far as the redundant jump, that was simply a mistake after a little shuffling i did...

I am about to have  to code a proc, , so im sure i'lll be needed some more help....need some better understanding of pointers....both base and stack....

Tedd

Quote from: seymour_glass on March 18, 2006, 03:55:46 AM
my teacher finally sat down with me and i finally got it figured out this afternoon.  I now see that if it were clearer, I could have picked them out myself.  That is something i would like to refine as this is my first architecture class, and I think it would be advantageous to be able to lay it out less messily.

As to the 0's thing...I was under the impression that I reallly only want that when i want it to stop there.  Example....

newLine  cr, Lf 

It seems that i wouldnt need that null zero unless i need the instruction to stop there....am i confused?  Although I probaby did need it to.....Just to get that out there before I get jumped...lol

Good to hear you're getting on with it :U
The point about a zero ending a string is that it tells the 'output' function when the string ends. It's not instructions, it's never executed. It's just a label to say "this is the end of this string." There are other ways of ending strings, but zero is the most common since you don't normally want to print zero (that's not the number 0, but a null).
No snowflake in an avalanche feels responsible.