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.
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
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
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.
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
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.
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
The use of call is discouraged. Try studying a simple example using PROTO and invoke - safer and easier to use.
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:
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.