Hi
I tried to understand the help MASM32 file about structures and wrote the following code below.
When I ran the program it gave me incorrect results and also it is a infinite loop.
Please help me.
Thanks
.686 ; create 32 bit code
;The MASM32 Runtime Library include file.
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Include \masm32\include\masm32rt.inc
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.Const
PRIMENUMBER Struct
Factor DWord 4 Dup (?)
Power DWord 4 Dup (?)
IsEvenPower DWord 4 Dup (?)
IsOddPower DWord 4 Dup (?)
PRIMENUMBER EndS
.Code
start:
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Call Main
inkey ; pause the screen while waiting for user to press any key
; to continue
exit
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Main Proc
Local WantContinue:DWord
Local counter:DWord
Local prme:PRIMENUMBER
; WantContinue is the sentinel value for while loop
;--------------------------------------------------------
; Eax, Ebx, Edx, and Esi are registers
Mov WantContinue, 0 ; initialize WantContinue to zero
Mov Eax, 1
.While (Eax <= 20)
Mov (prme[Eax]).Factor, 0
Mov (prme[Eax]).Power, 0
Mov (prme[Eax]).IsEvenPower, FALSE
Mov (prme[Eax]).IsOddPower, FALSE
Inc Eax
.EndW
.While ((WantContinue >= 0) && (WantContinue < -1))
; while WantContinue is greater than or equal to 0 And
; WantContinue is less than -1 do
print chr$(13, 10) ; a carriage return line feed will be outputted to the
; screen
Mov prme[1].Factor, 2
Mov prme[1].Power, 4
Mov prme[1].IsEvenPower, TRUE
Mov prme[1].IsOddPower, FALSE
Mov prme[2].Factor, 3
Mov prme[2].Power, 1
Mov prme[2].IsEvenPower, FALSE
Mov prme[2].IsOddPower, TRUE
Mov prme[3].Factor, 5
Mov prme[3].Power, 6
Mov prme[3].IsEvenPower, TRUE
Mov prme[3].IsOddPower, FALSE
Mov prme[4].Factor, 7
Mov prme[4].Power, 7
Mov prme[4].IsEvenPower, FALSE
Mov prme[4].IsOddPower, TRUE
print chr$(13, 10)
Mov Eax, 1
.While Eax <= 4
print str$(prme[Eax].Factor)
print chr$(13, 10)
print str$(prme[Eax].Power)
print chr$(13, 10)
print str$(prme[Eax].IsEvenPower)
print chr$(13, 10)
print str$(prme[Eax].IsOddPower)
print chr$(13, 10)
Inc Eax
print chr$(13, 10)
inkey
.EndW
Mov WantContinue, sval(input("Enter -1 to quit program : "))
Invoke ClearScreen ; clears the screen
.EndW
print chr$(13, 10)
Ret
Main EndP
End start
You are getting an endless loop because the second while loop is using EAX as a loop counter, and the print macro (and the functions that it calls) does not preserve the value of EAX. So after the first call to the print macro the value that you loaded into EAX is lost. For something like this instead of EAX you should be using one of the registers that are preserved by the Windows functions and by the MASM32 macros and procedures. This normally means EBX, ESI, or EDI.
Once again, looking at your code it's hard to know exactly what you are trying to do, so it's hard to know how to reply. I'm going to guess that you want to work with an array of structures of type PRIMENUMBER.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
PRIMENUMBER struct
factor DWORD ?
power DWORD ?
isEven DWORD ?
isOdd DWORD ?
PRIMENUMBER ends
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
call Main
inkey "Press any key to exit..."
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Main proc uses ebx esi
LOCAL pn[4]:PRIMENUMBER
; ---------------------------------------------------------------
; For this code there is no need to set the structure elements to
; 0, but if there were this is much easier than coding a loop.
; ---------------------------------------------------------------
invoke RtlZeroMemory, ADDR pn, SIZEOF pn
; --------------------------------------------------------------
; For the destination operands in the code below, pn represents
; the base address of the structure array, the number in the []
; brackets is the offset of the array element from the base
; address, and the ".factor", ".power", ".isEven", and ".isOdd"
; represent the offsets of the structure members within the
; array element.
; --------------------------------------------------------------
mov pn[00].factor, 2
mov pn[00].power, 4
mov pn[00].isEven, TRUE
mov pn[00].isOdd, FALSE
mov pn[16].factor, 3
mov pn[16].power, 1
mov pn[16].isEven, FALSE
mov pn[16].isOdd, TRUE
mov pn[32].factor, 5
mov pn[32].power, 6
mov pn[32].isEven, TRUE
mov pn[32].isOdd, FALSE
mov pn[48].factor, 7
mov pn[48].power, 7
mov pn[48].isEven, FALSE
mov pn[48].isOdd, TRUE
; -------------------------------------------------------------
; To encode the addresses correctly, MASM must know what ESI is
; pointing to. Either of the following 2 methods will work.
; In the loops ESI holds the address of the structure array,
; and EBX is used as a loop counter.
; -------------------------------------------------------------
xor ebx, ebx
lea esi, pn
.WHILE ebx < 4
print str$([esi].PRIMENUMBER.factor),13,10
print str$([esi].PRIMENUMBER.power),13,10
print str$([esi].PRIMENUMBER.isEven),13,10
print str$([esi].PRIMENUMBER.isOdd),13,10
add esi, 16
inc ebx
.ENDW
inkey
ASSUME esi:PTR PRIMENUMBER
xor ebx, ebx
lea esi, pn
.WHILE ebx < 4
print str$([esi].factor),13,10
print str$([esi].power),13,10
print str$([esi].isEven),13,10
print str$([esi].isOdd),13,10
add esi, 16
inc ebx
.ENDW
ASSUME esi:NOTHING
ret
Main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
Hi Michael,
In my program that you corrected, I was trying to create a structure each time a prime number is factored out in a positive integer greater than or equal to 2.
How would you create a large enough array of structures to call the array of structure each time a prime number is factored out? I think the maximum array of structures that I will create is eight.
It is hard to tell how many prime number factors there will be in each positive integer so a loop will be used. How do you implement the loop n times?
For example, the positive integer 30030,
The prime number factors of 30030 are 2, 3, 5, 7, 11, and 13.
The prime factorization of 30030 = 2 x 3 x 5 x 7 x 11 x 13
In this example above, I would create array of structures six times since there are 6 different prime number factors
Another example, the positive integer 108
The prime number factors of 108 are 2, and 3
The prime factorization of 108 = 2 x 2 x 3 x 3 x 3 or 2^2 * 3^3 or 4 * 27
Only two array of structures will be created for the positive integer 108 because of two prime number factors.
-----------------------------------------------------------------------------------------------------------
what does "invoke RtlZeroMemory, ADDR pn, SIZEOF pn" mean and do?
what does "ASSUME esi:NOTHING" mean and do?
-----------------------------------------------------------------------------------------------------------
Thanks Michael
Quotewhat does "invoke RtlZeroMemory, ADDR pn, SIZEOF pn" mean and do
It calls the Windows RtlZeroMemory function, passing it the address and size of the local buffer pn. Buffers created by LOCAL are not initialized to any particular value. So in code where the buffer needs to be initialized, and where the buffer is more than about 8-12 bytes long, it's easier to call a function to do that than it is to write code to do that.
Quotewhat does "ASSUME esi:NOTHING" mean and do
ASSUME esi:PTR PRIMENUMBER tells MASM to assume that ESI holds a pointer to a PRIMENUMBER structure, and ASSUME esi:NOTHING cancels that assumption.
Hi Michael,
How do you use a MASM32 program to initialize the items of a record instead of manually setting the values to the items of a record when using a loop?
Please reply.
Thanks.
See Structures and Unions in the MASM Programmer's Guide, about half way down the page here (http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Chap_05.htm).
Hi Michael,
Thanks for your help!
I figured out how to do it by your examples.