News:

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

Variables are not being store properly?

Started by unktehi, March 21, 2009, 08:28:34 PM

Previous topic - Next topic

unktehi

Note: WriteString is a macro that writes the contends of edx to the console

Can someone help me understand why the values of the variables at the end of the application end up displaying the same value, when, right after their askInput macro the variables have the correct value?


.code
main PROC
   
   askInput message1, messageSize1, var1
   mov var1, edx
   call WriteString
   
   askInput message2, messageSize2, var2
   mov var2, edx
   call WriteString
   
   mov edx, var1
   call WriteString
   mov edx, var2
   call WriteString
   
   ;writeMessage label2, label2Size, var2, var2Size
   ;writeMessage label1, label1Size, var1, var1Size     

   INVOKE ExitProcess,0
main ENDP
END main





When this program runs, here is the sample output if I type in firstName for first name and lastName for last name:

Enter First Name:
firstName <-- my input
firstName <-- from WriteString after first askInput macro
Enter Last Name:
lastName <-- my input
lastName <-- from WriteString after 2nd askInput macro

lastName <-- WriteString var1?

lastName <-- WriteString var2?

shouldn't these last two strings be different?


dedndave

not sure about this, actually, as i am fairly new to 32-bit, myself
but, try this................

.data
message1 DB "Enter First Name: ", 0dh, 0ah
messageSize1 DW ($ - message1)
var1 DW ?
var1Size DW ($-var1)+20
var2 DW ?
var2Size DW ($-var2)+20

unktehi

Unless I'm not catching the other changes, are the only changes you made changing DWORD to DW, etc?

I believe those are legacy directives - I don't think changing those would make a difference. 
I haven't used any of those, but I thought DW was used for word and DD was used for Doubleword?

Either way, I tried switching them to the legacy directives and it worked exactly the same way...

PBrennick

Looks like you are mixing up your handles. You are writing the value of STD_OUTPUT_HANDLE and STD_INPUT_HANDLE to the same variable, stdInHandle. Create a variable called stdOutHandle and place the value of STD_OUTPUT_HANDLE there and fix this:

stdInHandle,         ; console output handle

Paul
The GeneSys Project is available from:
The Repository or My crappy website

unktehi

I should probably change that anyway because that IS confusing.  However, it doesn't appear to have made any affect on the behavior of the code.

BogdanOntanu

Take the time and find the most simple and clear example of what do you think that it is not working in your program.

It takes too much time for people to browse more that a few lines of code especially when it is written in a confusing and not organized mode.

Hence please streamline your code to the minimum number of lines that clearey show what you think that it is going wrong.

This will help you getting help ;)
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

unktehi

I've modified/taken out all of the code but the code that seems to be displaying strange results - hopefully this will help.

BogdanOntanu

Quote from: unktehi on March 21, 2009, 11:55:24 PM
I've modified/taken out all of the code but the code that seems to be displaying strange results - hopefully this will help.

Unfortunately this is not what I wanted to teach you.

1) First of all when you make a mistake in the past and you do realize today that it was a mistake you DO NOT return in time in order to fix it ... Instead you improve yourself today.

In the same way you should have not edited your original message but instead you should have made a new post here at the end of this thread.

It is very non polite to edit a message (other than correcting errors) AFTER somebody has answered to it. In this way you are making their answers hard to understand and to follow. Also please not that this messages are not only for your understanding but can also serve for others to learn.

2) Suddenly big chunks of you code disappeared. yes it does make things smaller and slightly easier to understand BUT what if the error is exactly in the missing parts?

Both of WriteString procedure and askInput macro could contain errors. Well it is more likely that the error is in code that you have been written rather than in your book's / teacher's code.

Hence I find it amusing that you "document" the Write String procedure but you fail to document the askInput macro.

Then if you streamline some code it is still required to show all relevant parts that are needed to make it work. Data definitions and macros that you have written and it must compile and run as it is.

I did not say that it would be so easy as editing out some lines from your sample code.

3) What I wanted to teach you was different.

a) You should have streamlined your code to a minimum that is working as expected based on your current level of understanding.
b) Then you should have added new code in small steps ... one at a time ... until the "wrong" behavior would have emerged.

c) At that point you  would have found a closer location of your problems and you would have a better chance of understanding where your mistake is.

IF after doing this kind of detective actions your still could not find the error then we would have had a much better explanation of what is going wrong and where you suspect that the error is in your code.

I never expected that you will cut relevant portions from your code or that you would edit your original message... mea culpa.

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

BogdanOntanu

However based on this code:

.code
main PROC
   
   askInput message1, messageSize1, var1
   mov var1, edx
   call WriteString
   
   askInput message2, messageSize2, var2
   mov var2, edx
   call WriteString
   
   mov edx, var1
   call WriteString
   mov edx, var2
   call WriteString
   
   INVOKE ExitProcess,0
main ENDP
END main


And assuming that WriteString is working "as expected" then it becomes obvious that the only possible error is inside "askInput" macro or in your data definitions.

I am curios: what is the purpose of sending "var1" (contents or offset?) as a parameter to your macro and then in the very same line you write EDX register contents to the "var1" location?

It looks strange to me but it is not possible to say without seeing the code for "askInput".

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

unktehi

I'd agree with you except that after this line:

askInput message1, messageSize1, var1

WriteString writes out what is currently in edx - which is correct here.  In this instance, I'm also moving the value of edx into var1 to store.

Then WriteString is also writing the correct value of edx after this line:

askInput message2, messageSize2, var2

Once a value is moved into edx using the mov directive, isn't the value completely replaced? At the end of my askInput macro I have the variable value being moved into edx.

So then, how would var1 change to the value of var2 in this area of my code?

mov edx, var1
call WriteString
mov edx, var2
call WriteString

The way I see it, my macro, other than storing a value in edx, should not touch var1. Var1 should not be touched after the first iteration of askInput.



BogdanOntanu

Quote from: unktehi on March 22, 2009, 01:28:50 AM
I'd agree with you except that after this line:

askInput message1, messageSize1, var1

WriteString writes out what is currently in edx - which is correct here.  In this instance, I'm also moving the value of edx into var1 to store.

Then WriteString is also writing the correct value of edx after this line:

askInput message2, messageSize2, var2

So far so good. But again I see no purpose for sending "var1" or "var2" as a parameter to your macro since the macro apparently returns the input value in EDX register...

Quote
Once a value is moved into edx using the mov directive, isn't the value completely replaced?

Of course it is... anything that was before in EDX is lost forever and ever...

Quote
At the end of my askInput macro I have the variable value being moved into edx.

This statement I find dubious...

Quote
So then, how would var1 change to the value of var2 in this area of my code?

mov edx, var1
call WriteString
mov edx, var2
call WriteString

yes it is quite "impossible" ... UNLESS you make an error somewhere else ;)

Quote
The way I see it, my macro, other than storing a value in edx, should not touch var1. Var1 should not be touched after the first iteration of askInput.

Of course... "the way YOU see it". However computers are notorious for not doing what you want or hope or "your way" but instead computers do EXACTLY as you INSTRUCT them to do... no matter how wrong and illogical your instructions might be.

Hence I still suspect that there is an error somewhere in you macro or maybe in your data definitions.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

unktehi

Your right, I originally had var1 passed as an argument because I was going to have the macro return a new value inside that variable.  BUT, it is not needed with how I am approaching it now.  I've deleted the the arguments of var1 and var2 from the askInput lines (and also modified my macro so it doesn't complain).

Changing that, although I can see was necessary for clarification, didn't change the behavior.

So then here, because I deleted it all from my original post, is the askInput macro:

askInput MACRO myCommand, messageSize
   INVOKE GetStdHandle, STD_OUTPUT_HANDLE
   mov stdInHandle,eax
   
   INVOKE WriteConsole,
   stdInHandle,         
   ADDR myCommand,          
   messageSize,         
   ADDR myBytes,         
   0               
   
   INVOKE GetStdHandle, STD_INPUT_HANDLE
   mov stdInHandle, eax
   
   INVOKE ReadConsole,
     stdInHandle,
     ADDR buffer,
     BufSize - 2,
     ADDR myBytes, 0
    
   mov edx, OFFSET buffer
   
ENDM


Bufsize is set above as:

BufSize = 80

Here is the data definitions for these variables:

message1 BYTE "Enter First Name: ", 0dh, 0ah
messageSize1 DWORD ($ - message1)
buffer BYTE BufSize DUP(?),0dh,0ah
stdInHandle HANDLE ?
myBytes DWORD ? ; Number of bytes written or read

BogdanOntanu

So... your macro is returning "OFFSET Buffer" in EDX ...

However it is the very same buffer each and every time :D

hence the very same buffer is re-used and made dirty after each macro instance.

1) First your var1 contents become "offset buffer"
you print this and it is OK

2) Your var2 contents also become "offset buffer"
You print this and it is OK

However at this time you can not print the initial buffer content because it was overwritten by the new input.

Hence at this time var1 is useless because it contains a pointer to the very same buffer where you have written your seccond input...

Got it?

Apparently what you fail to understand it that you must store the input string somewhere, each string into his own buffer or else you will lose them when you re-use the buffer.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

PBrennick

As Bogdan is saying as as I said before. It is poor programming practice to do these type of things. You should not have one variable for two handles as I said before. How you code needs to be done in a logical way. Make separate variables for each specific usage and DO NOT share their usage. You will just confuse yourself and us. Same goes for strings.

Sorry to interrupt, Bogdan, but what he is doing is just wrong on too many levels.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

unktehi

Quote from: BogdanOntanu on March 22, 2009, 02:05:21 AM
So... your macro is returning "OFFSET Buffer" in EDX ...

However at this time you can not print the initial buffer content because it was overwritten by the new input.

Hence at this time var1 is useless because it contains a pointer to the very same buffer where you have written your seccond input...

Got it?


I think so, so if edx is returning the OFFSET of Buffer, then shouldn't I be able to derefence the edx by putting brackets around it. (According to the 'Introduction to Assembler' 'Addressing and Pointers' section, "Using square brackets around EAX gives access to the information at the address in EAX.") Then, by moving the derefenced value (the actual information) into either a variable name or another register, wouldn't it access the information at the new address of the new variable?