I've been looking quite a bit lately at the source code for VICE, a c64 emulator. I still work on it and enjoy tweaking the faux hardware in ways we couldn't do in the 80s, so looking at the source really helps. But I'm not really a "C" guy, so when trying to make conversions (in my head) to assembly I see a lot of "->" in the code. I'm wondering... in layman's terms, and since it's not COM code, does that just refer to members of a structure, something like "structure.member"?
I have some C reference here (and do look at it) but sometimes it just doesn't sink in the right way.
Thanks. I'm grateful for any help.
probably shift right
nope
it's a "pointer to a structure member"
http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B (http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B)
"didn't you see the arrows?"
"what arrows? i didn't even see any indians"
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
/*
typedef struct tagPOINT {
LONG x;
LONG y;
} POINT, *PPOINT;
*/
int main(void)
{
POINT p;
PPOINT pp = &p;
int x,y;
p.x = 1; // line 19
p.y = 2; // line 20
x = p.x; // line 22
y = p.y; // line 23
printf("%d\t%d\n",x,y);
x = pp->x; // line 27
y = pp->y; // line 28
printf("%d\t%d\n",x,y);
getch();
return 0;
}
_TEXT SEGMENT
_pp$ = -20 ; size = 4
_x$ = -16 ; size = 4
_y$ = -12 ; size = 4
_p$ = -8 ; size = 8
_main PROC NEAR
; File c:\program files\microsoft visual c++ toolkit 2003\my\structmember\test.c
; Line 14
push ebp
mov ebp, esp
sub esp, 20 ; 00000014H
; Line 16
lea eax, DWORD PTR _p$[ebp]
mov DWORD PTR _pp$[ebp], eax
; Line 19
mov DWORD PTR _p$[ebp], 1
; Line 20
mov DWORD PTR _p$[ebp+4], 2
; Line 22
mov ecx, DWORD PTR _p$[ebp]
mov DWORD PTR _x$[ebp], ecx
; Line 23
mov edx, DWORD PTR _p$[ebp+4]
mov DWORD PTR _y$[ebp], edx
; Line 25
mov eax, DWORD PTR _y$[ebp]
push eax
mov ecx, DWORD PTR _x$[ebp]
push ecx
push OFFSET FLAT:$SG74392
call _printf
add esp, 12 ; 0000000cH
; Line 27
mov edx, DWORD PTR _pp$[ebp]
mov eax, DWORD PTR [edx]
mov DWORD PTR _x$[ebp], eax
; Line 28
mov ecx, DWORD PTR _pp$[ebp]
mov edx, DWORD PTR [ecx+4]
mov DWORD PTR _y$[ebp], edx
; Line 30
mov eax, DWORD PTR _y$[ebp]
push eax
mov ecx, DWORD PTR _x$[ebp]
push ecx
push OFFSET FLAT:$SG74393
call _printf
add esp, 12 ; 0000000cH
; Line 32
call _getch
; Line 33
xor eax, eax
; Line 34
mov esp, ebp
pop ebp
ret 0
_main ENDP
_TEXT ENDS
set file="test"
set PATH=C:\Program Files\Microsoft Visual C++ Toolkit 2003\bin;%PATH%
set INCLUDE=C:\Program Files\Microsoft SDK\include;C:\Program Files\Microsoft Visual C++ Toolkit 2003\include;%INCLUDE%
set LIB=C:\Program Files\Microsoft SDK\lib;C:\Program Files\Microsoft Visual C++ Toolkit 2003\lib;%LIB%
cl /W4 /FA %file%.c
pause
1 2
1 2
If you have a function structure like this
a.test
a.test2
a.test3
and you access it like this a->test
the assembly code is
mov eax,a
call [eax].test
call [eax].test2
call [eax].test3
> mov eax,a
Better use mov eax, offset a ;-)
Thanks. Makes sense to me now, and reading the C source just became 100% clearer. That wasn't so complicated, was it?
Man, the mind is a crazy thing sometimes...
"->" is also known as "smart pointer". ;)
Greenhorn
Quote from: Greenhorn on December 20, 2012, 03:19:56 AM
"->" is also known as "smart pointer". ;)
I prefer the dumb ones in assembler, at least they obey to my orders 8)
Found this jewel here (http://stackoverflow.com/questions/106508/what-is-a-smart-pointer-and-when-should-i-use-one):
QuoteA smart pointer is a class that wraps a "bare" C++ pointer, to manage the lifetime of the object being pointed to.
With "bare" C++ pointers, the programmer has to explicitly destroy the object when it is no longer useful.
// Need to create the object to achieve some goal
MyObject* ptr = new MyObject();
ptr->DoSomething();// Use the object in some way.
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception....
A smart pointer by comparison defines a policy as to when the object is destroyed. You still have to create the object, but you no longer have to worry about destroying it.
Translated to Masm, what is an object whose policy is defined as "has a limited lifetime and gets destroyed automatically"? Right, here it is:
MyProc proc
LOCAL rc:RECTSmart, isn't it?
yes - it seems less confusing in asm
INVOKE ClientToScreen,hWnd,addr rc.right
I believe EVERYTHING is less confusing in assembler. For the life of me, I can't understand for a second why these languages are so popular. They are just so overly-complicated with fancy words, etc. I seldom have trouble deciphering assy code--even crazy, complex arrays--but give me a C++ listing and it might as well be that Chinese stuff jj was writing yesterday. Assembly code is so much more straight-forward. And spaghetti code will always be spaghetti code, no matter what language it is written in. I really just don't get it...
The good thing is I now understand a "smart pointer." And I appreciate the clarity. Thank you.
Quote from: satpro on December 20, 2012, 07:58:39 AM
The good thing is I now understand a "smart pointer." And I appreciate the clarity. Thank you.
Hm, but at least the posting of jj is plain silly ( for jj: albern ). What'S called a local struct in assembly is also called a local struct in C and C++, not a "smart pointer".
I confess I don't like "smart" anything much, it is usually an extra complication layer to address some act of stupidity that should not have been made in the first place. Its also why I prefer generic assembler data SIZES with no phony types, I would prefer to rely on how I name them (pThisOrThat) rather than some heavy handed data type enforcement. C type checking nearly drives me NUTZ but then I have been free of it for many years with MASM so I may be biased.
Best way to confuse a person learning assembler is to up the clutter level, try and ape another language's format or commit it to an ever increasing number of phony data types, variable naming while knowing "how big" a variable is produces a far more reliable direction for people to understand assembler code.
hMyControl = DWORD (handle)
pMyMemory = DWORD (pointer)
uMyVar = DWORD (unsigned 32 bit integer)
lMyVar = DWORD (signed 32 bit integer)
hWndMain = DWORD (window handle)
Simple ain't it. :biggrin:
Quote from: hutch-- on December 20, 2012, 04:48:18 PM
Simple ain't it. :biggrin:
Yes :biggrin:
https://en.wikipedia.org/wiki/Rhynia (https://en.wikipedia.org/wiki/Rhynia) was also very simple - it got extinct 400m years ago. Probably simplicity is not a value in itself? The "everything's a DWORD" idea was simple, I agree, but unfortunately not the simple things, but those with good adaptation capabilities are going to survive. :icon_mrgreen:
Quote from: japheth on December 20, 2012, 03:19:02 PM
Hm, but at least the posting of jj is plain silly ( for jj: albern ). What'S called a local struct in assembly is also called a local struct in C and C++, not a "smart pointer".
The word "silly" hurts me a little bit, because it comes from a genius, one of the very few members of the "bloat without the power" fraction who is actually able to produce useful output - kudos for JWasm :t
On contents: I didn't write that all local structs in C are called smart pointers. I just wrote that the Chinese in the "jewel" I quoted above could be translated to "if you need an idiot-proof 'smart' memory 'object' that does not require to be 'destroyed' after usage, just use LOCAL myobject:MYSTRUCTURE". IMHO this fits nicely to the claim "object whose policy is defined as 'has a limited lifetime and gets destroyed automatically'".
Merry Christmas to you, too, Japheth. And thanks for the honour to meet a programming genius here :icon14:
i thought like Hutch, at first
but, lately, i have been trying to type my data correctly
it helps me to to see what things are at a glance
and i don't think the assembler cares one way or another
if you try to port some 32-bit code to 64-bit....
hbrBlack HBRUSH ?
and
WndProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
might save you some conversion effort
Quote from: jj2007 on December 20, 2012, 09:32:20 PM
The word "silly" hurts me a little bit,
That's good, that's very good. As I recall, I recently mentioned my strong conviction that a successful learning process requires PAIN. So you're definitely on a good way.
Quote
...because it comes from a genius, one of the very few members of the "bloat without the power" fraction who is actually able to produce useful output
Well ... :icon_mrgreen:
QuoteMerry Christmas to you, too, Japheth.:
I've converted to Islam recently - because it's always good to be with the winner. :bgrin:
Quote
... might save you some conversion effort
Yes. Additionally, if you're using symbolic debugging, you can easily watch not just the value of a pointer, but the values of the pointer's target.
Quote from: japheth on December 20, 2012, 11:23:58 PM
Quote from: jj2007 on December 20, 2012, 09:32:20 PM
The word "silly" hurts me a little bit,
That's good, that's very good. As I recall, I recently mentioned my strong conviction that a successful learning process requires PAIN. So you're definitely on a good way.
:greensml:
:biggrin:
> and i don't think the assembler cares one way or another
It doesn't.
> if you try to port some 32-bit code to 64-bit....
I have a theory on porting, rewrite it in the native format.
> I agree, but unfortunately not the simple things, but those with good adaptation capabilities are going to survive.
Yes, like the shark, crocodile and a number of others, get it right the first time and you don't have to adapt. :P
Quote from: japheth on December 20, 2012, 11:23:58 PM
I've converted to Islam recently - because it's always good to be with the winner. :bgrin:
japheth,
Personally I feel islam and christianity are both way over rated, atheism is the only real path to salvation. :biggrin:
Quote from: Bill Cravener on December 21, 2012, 02:05:41 AM
Personally I feel islam and christianity are both way over rated, atheism is the only real path to salvation. :biggrin:
Yes, laugh - as long as you can! First we'll take Berlin, then we take Manhattan! :shock:
that's not a religion !
(http://i2.listal.com/image/1771509/500full.jpg)