News:

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

need help for my code

Started by MrBogus, March 24, 2008, 12:47:45 AM

Previous topic - Next topic

MrBogus

Hello,

I need help to correct my code to convert/evaluate c++ codes in order for me to understand assembler.

here is the c++ code to be converted in asm:

code
#include <iostream>
using namespace std;

void f()
{
     static int x = 2;
     int y = 3;
     int z = 5;
     cout << x << " " << y << " " << z << endl;
     x = 1;
     y = 2;
     z = 3;
}
void g()
{
     static int x = 44;
     int y = 50;
     cout << x << " " << y << endl;
     y = 22;
     x = y;
}
int main()
{
    f();
    f();
    g();
    g();

    system("pause");
   
}


here is my asm code:


.486                                   
    .model flat, stdcall                   
    option casemap :none                   

    include \masm32\include\windows.inc
    include \masm32\macros\macros.asm


    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc

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

.data
x dd 0
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
f proc
mov x, 2 ; static int x = 2;
LOCAL y:3 ; int y = 3;
LOCAL z:5 ; int z = 5;
print chr$(x, y, z,13,10) ; cout << x << " " << y << " " << z << endl;
mov x, 1 ; x = 1;
mov y, 2 ; y = 2;
mov z, 3 ; z = 3;
ret
f endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
g proc
mov x, 44 ; static int x = 44;
LOCAL y:DWORD ; int y = 50;
print chr$(x, y,13,10) ; cout << x << " "  << y << endl;
mov y, 22 ; y = 22;
mov eax, y ; x = y;
mov x, eax

ret
g endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
call main
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc
call f ; f();
call f  ; f();
call g  ; g();
call g  ; g();
ret
main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start



This is my expected output.

2 3 5
1 3 5
44 50
22 50


Sorry for being too noob, :dazzled: but I think this will be a way for me to learn.
I will appreciate any help/correction anyway. Thanks.

MichaelW

The chr$ macro is designed to handle mixed text and byte data - it cannot do conversions of numbers to strings. I think something like this will do what you want:

print ustr$(x)," "
print ustr$(y)," "
print ustr$(z),13,10


See masm32\help\hlhelp.hlp
eschew obfuscation

jj2007

Below is your code in a format that doesn't throw errors, but I haven't checked your logic yet 'cause it's 2:30 in the morning here.
Hint: LOCAL x:3 won't fly - see below the correct version; also nothing between proc and LOCAL.
As a general rule, try to assemble your code before posting it, and highlight the errors you get, so that we can help you better.
Welcome in the club!

.486                                  
   .model flat, stdcall                  
   option casemap :none                  

   include \masm32\include\windows.inc
   include \masm32\macros\macros.asm


   include \masm32\include\masm32.inc
   include \masm32\include\gdi32.inc
   include \masm32\include\user32.inc
   include \masm32\include\kernel32.inc

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

.data
x dd 0
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
call main
   exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc
call f ; f();
call f  ; f();
call g  ; g();
call g  ; g();
ret
main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
f proc
LOCAL y:DWORD
LOCAL z:DWORD
mov x, 2
mov y, 3
mov z, 5

; print chr$(x, y, z,13,10) won't work
print str$(x)
print chr$(", ")
print str$(y)
print chr$(", ")
print str$(z)
print chr$(13,10)


mov x, 1
mov y, 2
mov z, 3
ret
f endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
g proc
LOCAL y:DWORD ; int y = 50;
mov x, 44 ; static int x = 44;
print str$(x)
print chr$(", ")
print str$(y)
print chr$(13,10)
mov y, 22 ; y = 22;
mov eax, y ; x = y;
mov x, eax

ret
g endp


end start

xmetal

First of all, static variables declared in different procedures are independent. Secondly, initialization of static variables takes place only once, that is, before the first time the procedure is called which declared it.

So your data section should look something like this:


.data
f_x dd 2
g_x dd 44


Make sure you first understand well the concept of static variables in C/C++, it is actually a high-level concept which even a non-assembler programmer can understand.

Also, usually there is more than one way to implement an HLL concept in low-level code.

MrBogus

Hello MichealW,

Thanks for giving me a reference for that macro and I think I'll need to look a lot of macro from there.  :U

Hello jj2007,

Thanks for the correction of my code.
I got it! There are no errors now and make it right.  :U

Hello xmetal,

Yes, I'm worried in static variable x. That's was I'm going to ask! As I have searched, static local variables is initialized only once. Each initialization does not occur every time the function that contains it is called. Now, I understood what is a static local variable.   :U

I feel now that I'm going into a right direction but still needs more c++ codes to convert in order for me to understand assembler.  :lol Hence, this will be a good practice for me as a beginner. hehe
This is my first code in MASM and I'm pretty enjoying this much...  I'll try another c++ program to convert.

Here is my code that now works WITH your help::clap:

.486                                   
    .model flat, stdcall                   
    option casemap :none                   

include \masm32\include\windows.inc
    include \masm32\macros\macros.asm


include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc

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

.data
f_x dd 2
g_x dd 44

.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
f proc
LOCAL y:DWORD ; int y = 3;
LOCAL z:DWORD ; int z = 5;
;mov f_x, 2 ; static int x = 2;
mov y, 3
mov z, 5

print str$(f_x), " " ; cout << x << " " << y << " " << z << endl;
print str$(y), " "
print str$(z), " ", 13, 10

mov f_x, 1 ; x = 1;
mov y, 2 ; y = 2;
mov z, 3 ; z = 3;
ret
f endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
g proc
LOCAL y:DWORD ; int y = 50;

;mov g_x, 44 ; static int x = 44
mov y, 50
print str$(g_x)," "
print str$(y)," ",13,10

mov y, 22 ; y = 22;
mov eax, y ; x = y;
mov g_x, eax

ret
g endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
call main
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc
call f
call f
call g
call g
ret
main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start


"maraming salamat!" a filipino word that means "many thanks!"

Regards,
edward

MrBogus

Hello,

I got another problem on local variables and in parameter passing.

Here is my c++ code to be converted in asm:

#include <iostream>
using namespace std;
int x = 1, y = 2;
void f(int x)
{
     int y = 7;
     x = y;
     cout << x << " " << y << endl;
}

int main ()
{
    f(x);
    f(y);
   
    cout << x << " " << y << endl;
   
    system("pause");
}


Here is my asm code:

.486                                   
    .model flat, stdcall                   
    option casemap :none                   

include \masm32\include\windows.inc
    include \masm32\macros\macros.asm


include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc

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

.data
x dd 1 ;int x = 1, y = 2;
y dd 2
.data?

.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
call main
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
main proc
push x ;f(x);
call f

push y ;f(y);
call f

print str$(x), " " ;cout << x << " " << y << endl;
print str$(y), 13, 10

ret
main endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
f proc x:DWORD ;void f(int x)
LOCAL y:DWORD ;int y = 7;
mov y, 7
mov eax, y ;x = y;
mov x, eax

print str$(x), " " ;cout << x << " " << y << endl;
print str$(y), 13,10

ret

f endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


My expected output should be:

7 7
7 7
1 2
Press any key to continue . . .


but I got a compile error like this:

Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

Assembling: 7p34.asm
7p34.asm(43) : error A2005: symbol redefinition : x
7p34.asm(44) : error A2005: symbol redefinition : y
compile error !
Press any key to continue . . .


Is there any way I can still use variable y to be used as a local variable even though it is already declared as a global variable? And the same thing on the parameter x.  :dazzled: Thanks in advance.

Ossa

Quote from: MrBogus on March 25, 2008, 02:55:40 PM
Is there any way I can still use variable y to be used as a local variable even though it is already declared as a global variable? And the same thing on the parameter x.  :dazzled: Thanks in advance.

No, you can't have them named the same, as the assembler doesn't know which one to use inside the procedure.

You'll have to rename either the local or the global. You could call the global something like g_x to differentiate the variable names.

Ossa
Website (very old): ossa.the-wot.co.uk

jj2007

The use of call is discouraged. Try studying a simple example using PROTO and invoke - safer and easier to use.

modchip

Quote from: jj2007 on March 25, 2008, 05:56:28 PM
The use of call is discouraged. Try studying a simple example using PROTO and invoke - safer and easier to use.

I agree! The iczelion site and books has tons of examples.

BTW: Praktis lang nang praktis MrBogus!  :clap:

hutch--

Guys,

Don't be too fast to write off the PUSH/CALL syntax, while INVOKE and variations are useful and often help in clear coding, there are times when manual PUSH/CALL notation has its advantages. Stack forwarding to get arguments pushed as the result of other proc calls then just call the proc as all the args are already pushed onto the stack. You can at times do calculations between pushes instead of doing them first then storing the result in a variable.

As usual pick horses for courses.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php