News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

typedef for arrays

Started by johnsa, September 25, 2013, 01:26:23 AM

Previous topic - Next topic

johnsa

Hey,

Just curious if there is any way to setup something like the following:

anArray dq 100 DUP (0)

aStruct struct
a dd 0
b dd 0
ends

; create 100 aStructs..
; put pointers to them in anArray

now if you use proper types, IE: PTR aStruct instead of say just QWORD you get member listing when debugging in Visual Studio etc.
If you create a local array like: LOCAL myArray[100]:DWORD Visual studio correctly interprets this as a list and shows the 100 items.

Now is there any way to setup anArray to correctly reflect the items via a ptr variable?

I tried this:

p1 typedef PTR aStruct
p2 typedef PTR p1

myPointer p2 ?

lea rax,anArray
mov myPointer,rax

dedndave

not sure what you are trying to do with typedef, but...

aStruct struct
  a dd 0
  b dd 0
aStruct ends

    .data

anArray aStruct 100 dup(<>)

    .code

    ASSUME  EBX:Ptr aStruct

    mov     eax,anArray[ebx].b

;
;
;
    ASSUME  EBX:Nothing


in the structure definition, you have initialized a and b to 0
better if you leave them uninitialized, put it in the .DATA? section, and they will be 0 at startup

johnsa

Hey,

If I allocate the memory dynamically


invoke HeapAlloc,rv(GetProcessHeap),100*8
mov pArray,rax

I guess what I'm looking for is if there is anyway to cheat and get a PTR type[] (to an array) of dynamic size. Given that the assembler doesn't know the size of that array at assemble time.

dedndave

similar to before
use ASSUME with a register
after that, the assembler assumes that register is a pointer to that structure type
be sure and ASSUME  REG:Nothing when you are done, though   :P

you can also do it with an "override" - no ASSUME
    mov    eax,[ebx].aStruct.b
in that case, you'd have to add the pArray base

another way...
    mov     esi,pArray
    mov     eax,[esi+ebx].aStruct.b

johnsa

ASSUME works fine in terms of assembly time, and using structure types against a pointer in a register..

ie:

assume rax:PTR Struct
mov [rax].x,0
assume rax:nothing

or

mov [rax].Struct.x,0

or

mov (Struct PTR [rax]).x,0

but I'm trying to see it in the Visual Studio Debugger view (via locals/watches etc) where it uses the debug type info to ascertain the size / contents of the type etc.

dedndave

not sure about that one
if you can create some sort of public symbol, maybe

qWord

Use the type of the structure pointer (pX typedef ptr structX), add the variable to the watch window as: "mypointer,10", to see 10 elements of that array.
MREAL macros - when you need floating point arithmetic while assembling!

johnsa

Ahh... let me try that :) I wasn't aware of variable,x in the watch.. that will probably solve my problem.
If you hadn't guessed I've been implementing an OOP layer.. I've got generic lists which support primitives, objects, structs, strings etc.. so when I look at my list objects in the watches I want to see correctly typed items from it's backing-buffer.

Thanks!
John

qWord

Quote from: johnsa on September 25, 2013, 05:59:44 AMI've got generic lists which support primitives, objects, structs, strings etc..
I've done the same using "template-macros", which derives a new list-class from the type T (also a class) - therefore it would be interesting to see how you did it.
MREAL macros - when you need floating point arithmetic while assembling!

johnsa

Mine is still fairly basic and subject to some more refinement.. i've avoided inheritance because to be honest i hardly ever use it even in HL. What i do have though is something more like a protocol so that as long as classes have the same set of methods+args you can use the protocol as the type for invoking etc.

I learnt quite a bit from the original objects.inc, but I didn't like the way it required classes to be created.. so i re-did it all so i just have a single CLASS ENDCLASS definition and that automatically creates the static implementation/ptr types/vtbl stuff and obviously it's all x64/jwasm now.

I've pulled some cheats with my Lists so the primitive types act like normal growable arrays.. so no boxing to obj.types.. and cheated using the fact that macros support literal text in < >

so you can say mov myObject,$NEW(List<String>) or List<Int32> etc.

qWord

Quote from: johnsa on September 25, 2013, 06:36:21 AMi've avoided inheritance because to be honest i hardly ever use it even in HL. What i do have though is something more like a protocol so that as long as classes have the same set of methods+args you can use the protocol as the type for invoking etc.
sounds a bit like the COM ABI  8)

regards, qWord
MREAL macros - when you need floating point arithmetic while assembling!

johnsa

I guess there are some bits that map quite closely to COM but where possible without the overhead.

I have tentatively put ref counting in so that if one day I feel very ambitious I might implement something like ARC(osx style) but purely in debug mode.. it would at least tell you where memory leaks are, then you can fix it and disable the collection for release mode.

I like the idea of having the vtbl so i can change objects at runtime, like replacing the List objects Sort method with a delegate, but at the same time having $invoke which bypasses vtbl and goes straight to the proc with thisPtr.

I've been benchmarking everything as I go against c# and c++ 11/STL and Boost. Obviously c# wins hands down when it comes to the performance of NEW operators due to its sub-allocator, but you shouldn't be going around new'ing stuff in time-sensitive code anyway so a more useful comparison are the actual functions like String.ToLower, String.Replace, List.Add and so on.. and in those cases c++ is usually at least 2x c# and i've managed to ensure that no call is worse than 30% faster than the STL/Boost equivalent.

I've put all my phonetic matching and SSE4.2 string functions into the String class too so you can do direct phonetic comparisons.

qWord

I must admit that I've never had the intension to compare the OOP macros against the STL & co. - my idea was to teach MASM/jWasm (x32/64) the concept of OOP at a "not-to-low" level, which means inheritance, inline methods, late binding and some kind of delegates. The syntax is mix of c++ and c#, as far as possible with MASM/jWasm. The project is currently be on hold, because of some "design mistakes" ... mainly the fact that I've choose EBX/RBX to be the this pointer (also used to pass it to methods).
MREAL macros - when you need floating point arithmetic while assembling!

johnsa

Well it sounds very interesting! Probably a more "complete" solution than mine, I just needed something to deal with Strings and to have something like Lists/Vectors makes a lot of ugly code less painful to write and less likely to break. I've also create try catch throw macros so constructors can throw exceptions which also helps keep things clean.. and is particularly easy in x64 with the improved SEH.


jj2007

Quote from: johnsa on September 25, 2013, 06:36:21 AM
Mine is still fairly basic
Looks more like C/C++/C#. This is basic:
  Dim Rc() As RECT        ; create a dynamic array of RECT structures
  For_ ebx=0 To 9
        lea ecx, [ebx+100]
        mov Rc(ebx, left), ecx            ; assign some values
        lea ecx, [ebx+8*ecx+100]
        mov Rc(ebx, right), ecx
  Next
  For_ ebx=0 To 9        ; print them:
        Print Str$("%i", Rc(ebx, left)), Str$(", %i\n", Rc(ebx, right))
  Next


Seriously: It is remarkable that "almost dead" MASM sees a splendid revival, with projects like ObjAsm32 or SmplMath, and now yours going in the OOP/COM direction using 64 bits :t