Ok I don't know if I'm right or wrong but I found out some weird
"bugs":

1. SIZE - Doesn't give you the actual size, it returns 1
- Im sorry for my ignorance if this one always returns 1

...
SomeVariablesHere db "Some Text Here", 0
...

EG: SIZE SomeVariablesHere ---> returns 1

Expected Return Value: 14 (15 - plus the terminating
character)

2. * - By using this one you can multiply values
- Again, Im sorry for my ignorance, if this one actually is
allowed in TASM, because I was accustomed to using mul when
multiplying values

I was converting some win32 examples from masm(Tutorials from Iczelion) to tasm. The reason is that most of the tutorials
were incompatible with tasm (of course you can use the: masm - to use
masm commands). Anyway, I posted this similar code. The comments in
between codes will help clarify the things i've said.

This is Tutorial 4: Painting with text

You don't need a windows include here, i've translated those codes
such as WM_DESTROY to the appropriate hexadecimal values...

;-----------------------------------------------------------------------------
; 004.asm
;-----------------------------------------------------------------------------
; This is a win32 paint example with colors
;
; tasm32.EXE /s /r /ml /m4 004.asm
; tlink32.EXE -x -Tpe -aa 004,,,import32.lib
;
;-----------------------------------------------------------------------------

.386
.MODEL flat, stdcall

WNDCLASSEX STRUC
cbSize DWORD ?
Style DWORD ?
lpfnWndProc DWORD ?
cbClsExtra DWORD ?
cbWndExtra DWORD ?
hInstance DWORD ?
hIcon DWORD ?
hCursor DWORD ?
hbrBackground DWORD ?
lpszMenuName DWORD ?
lpszClassName DWORD ?
hIconSm DWORD ?
WNDCLASSEX ENDS

RECT STRUCT
left DD ?
top DD ?
right DD ?
bottom DD ?
RECT ENDS

PAINTSTRUCT STRUC
hdc DWORD ?
fErase DWORD ?
rcPaint RECT <>
fRestore DWORD ?
fIncUpdate DWORD ?
rgbReserved BYTE 32 dup(?)
PAINTSTRUCT ENDS

RGB MACRO red, green, blue
xor eax,eax
mov ah,blue
shl eax,8
mov ah,green
mov al,red
ENDM

EXTRN GetModuleHandleA : NEAR
EXTRN LoadIconA : NEAR
EXTRN LoadCursorA : NEAR
EXTRN CreateWindowExA : NEAR
EXTRN RegisterClassExA : NEAR
EXTRN GetMessageA : NEAR
EXTRN DispatchMessageA : NEAR
EXTRN PostQuitMessage : NEAR
EXTRN DefWindowProcA : NEAR
EXTRN ExitProcess : NEAR

EXTRN BeginPaint : NEAR
EXTRN CreateFontA : NEAR
EXTRN SelectObject : NEAR
EXTRN SetTextColor : NEAR
EXTRN SetBkColor : NEAR
EXTRN TextOutA : NEAR
EXTRN EndPaint : NEAR

.DATA

wcx WNDCLASSEX <SIZE WNDCLASSEX, 1h or 2h, WndProc, 0, 0, 0, 0, 0,
5 + 1, 0, WndClassName, 0>
hWnd DD 0
MSG DD 0, 0, 0, 0, 0, 0, 0
WndClassName DB "egi12", 0
WindowTitle DB "Win32 ASM : Paint With Colors", 0

rect RECT <>
ps PAINTSTRUCT <>
hDC DD 0
PaintText DB "A Paint Example", 0

hFont DD 0
FontType DB "script", 0


;--------------------------------
;Use for debugging
;--------------------------------
;EXTRN MessageBoxA : NEAR
;MsgTTL db "", 0
;MsgTXT db "", 0
;push 00h
;push OFFSET MsgTTL
;push OFFSET MsgTXT
;push 0
;call MessageBoxA
;--------------------------------

.CODE

Start:

push 0
call GetModuleHandleA
mov , eax

push 32512
push
call LoadIconA
mov , eax
push 32512
push
call LoadCursorA
mov , eax

push OFFSET wcx
call RegisterClassExA

push 0
push
push 0
push 0
push 600
push 600
push 75
push 225
push 10000000h or 0h or 0C00000h or 80000h or 40000h or 20000h
push OFFSET WindowTitle
push OFFSET WndClassName
push 00000100h or 00000200h
call CreateWindowExA
mov , eax

WindowMSGs:

push 0
push 0
push 0
push OFFSET MSG
call GetMessageA
or eax, eax
jz WmQuit
push OFFSET MSG
call DispatchMessageA
jmp WindowMSGs

WmQuit:

push 0
call ExitProcess

WndProc:

cmp DWORD ptr , 2h
je PQMSG
cmp DWORD ptr , 0Fh
je PaintMSG
jmp DefWindowProcA

PQMSG:

push 0
call PostQuitMessage
xor eax, eax
ret 16

PaintMSG:

push OFFSET ps
push
call BeginPaint
mov , eax

push OFFSET FontType
push 64 or 0
push 0
push 0
push 0
push 255
push 0
push 0
push 0
push 400
push 0
push 0
push 16
push 24
call CreateFontA

push eax
push
call SelectObject
mov , eax

RGB 200, 200, 50

push eax
push
call SetTextColor

RGB 0, 0, 255

push eax
push
call SetBkColor

;This is the part. I have to count the string length.
;Because when using SIZE PaintText it always return 1,
;thus printing only the first character of the whole
;entire string
;
;Output: ecx

push eax
push edi
mov edi, OFFSET PaintText
xor eax, eax
mov ecx, 0FFFFFFFFh
cld
repnz scasb
not ecx
dec ecx
pop edi
pop eax

;In the tutorials example it is SIZEOF ...
;SIZEOF(MASM) == SIZE(TASM)
;If you try to put in SIZE PaintText, it returns 1
;
;push SIZE PaintText

;Now for some weirder stuff. If you try this
;push SIZE PaintText * 3
;
;It will print out the first 3 characters of the string
;which is A P (A Space P)
;I didn't know that * could multiply values
;
;If you try push 3, this one will have the same output
;
;I really don't know, I wish somebody could clear this up

push ecx

push OFFSET PaintText
push 0
push 0
push
call TextOutA

push
push
call SelectObject

push OFFSET ps
push
call EndPaint

xor eax, eax
ret 16

END Start

The structures and equates were from Windows.inc provided by MASM32 v7.0

Another weird bug: tasm crashes when using that include file. It gives me a heap error.

Thanks!!!
:) :grin: :rolleyes: :confused: :stupid:
Posted on 2001-12-18 17:40:04 by stryker
1 - This could be because it is an array of bytes (each element is only 1 byte long). Try using SIZE on say a dword, if that is also 1, then there is a problem!

2 - You can only use * at compile time. In the example below, you have on some occasions things like "cmp DWORD ptr , 2h", and you cannot have 2 constant values in the instruction (+4 +4). The assembler knows that as they are constants, they can be rolled up into one, so the actual instruction is "cmp , 2h". The multiply is the same! It is provided for our convenience. It is much more readable to say "SIZEOF this_structure * number_of_elements" than to have "66", or some other arbitrary number that you the programmer must write (it also cuts down on errors too).
If you try to multiply some variable by another variable, the assembler will moan at you. You can of course multiply registers by 2, 4, and 8 (with certain exceptions) as in the lea instruction.

Mirno
Posted on 2001-12-18 18:55:16 by Mirno
Ive tried

push DWORD
or
push SIZE DWORD ;Error In Compiling

..Still doesnt work...

I Still need to count the length of the string then push that value...

For that DWORD ptr , 2h

But anyway the code above still works.

Thanks
Posted on 2001-12-18 19:19:31 by stryker
to get the size use following instruction:

data 'example',0
dataSize EQU $-data
Posted on 2001-12-18 21:31:03 by adapix
Thanks I have a routine up there that counts the string length:

push eax
push edi
mov edi, OFFSET PaintText
xor eax, eax
mov ecx, 0FFFFFFFFh
cld
repnz scasb
not ecx
dec ecx
pop edi
pop eax

Output: ecx now contains the length of the string

:)
Posted on 2001-12-18 22:22:15 by stryker
Do you have SIZEOF in TASM?
Posted on 2001-12-18 22:31:21 by bitRAKE
TASM doesn't have SIZEOF. TASM equivalent of SIZEOF is SIZE.
And I'm sure that when using SIZEOF PaintText(MASM)...It returns the length of PaintText but in TASM it doesn't.

:(
Posted on 2001-12-18 23:51:33 by stryker
MASM:

SIZEOF returns the byte length of a structure/label.

LENGTHOF returns the number of items.

Example:

What_Is_This dd 1,1,2,3,5,8,13,21

(SIZEOF What_Is_This) = 32

(LENGTHOF What_Is_This) = 8

(SIZE What_Is_This) = 4
Posted on 2001-12-19 00:17:21 by bitRAKE
hossa

at last one who maybe uderstand my stupid questions :)
i often have problems when i convert stuff from masm to tasm.

dont forget the hex2string convert in masm ,not aviable in tasm.
or some lib or inc files missing in tasm......

if you need help find more of this ,i like to help.
Posted on 2001-12-19 04:49:48 by Max
i forget to say:

to get the lenght of a string you can use "lstrlen"
call lstrlen ,offset STRING
eax = lenght

lstrcpy to copy
lstrcat to add to
Posted on 2001-12-19 04:52:32 by Max
Why not just give up on tasm and use masm?
Posted on 2001-12-19 05:04:27 by f0dder
------
Why not just give up on tasm and use masm?
------

lol hope not all think so :)
if there is a prob. with one then change to the next is not the way i like.

i think first what should i learn....masm what most use and for what i can found most samples ,or tasm what not so much people use and where its hard to find infos about.
so i use tasm :)

then try to disassemble with masm knowledge and then try it with tasm knowledge......tasm is much better !

hm sound stupid if a newbie say : tasm is better
but i like it and i will use ...no matter how hard it is to learn this or that.
at last im shure i get it working ,like all the other stuff i today use.
most is bad coded or look bad but as long as it does what i want it is totaly ok for me.

so i personal think there is no time to change to masm.

its like 99 people speak spanish and i speak english...to make it easy i stop english and speak spanish.
so english get lost.......not what i want !

i dont know enough about masm and why its not compatible to tasm or why tasm is not comp. to masm :)

I WILL LEARN TO CODE *rofl*
Posted on 2001-12-19 06:18:58 by Max
Fodder, last time i took a look at it, it was TASM V.1 (1988).
At that time, it was clear that TASM was not so bad as MASM was.

I don't know if the difference is yet effective today, as, since
that time, i never took any more any look at these two commercial
products, and i don't even care if they yet exist or not.

Now, we have free (Open Sources or public Sources) Assemblers:
NASM, SpAsm, FASM, Pass32,...

I feel free to push these ones because they are 'clean at a moral
point of vue'. I know that Hiro flames me down each time i raise
this Holly War argument, but i can't prevent, as this is my FIRST
choice criteria.

Pushing a commercial product, whereas moral compatible products are
available for free, is fighting against freedom in the programming
area. Just like electing a serial killer as President of US is
fighting against against human dignity. Just like eating industrial
food is fighting for the destruction of nature by Dos-Santos and
friends. Just like having an Panel up there,
after the candels enlightment in Manhattan, is fighting for the
destruction of Third World Countries by US... And so on...

Now, if you mean to only talk of 'quality', this would be a lengthy
thread. I would not debate, as i have no idea of what others call
'quality', and because quality is a second hand problem in Open Source.
I mean, if the quality of an Open Source Assembler is not good enough
for the supposed great programmer you surely are, you just are allowed
to improve it. I am convinced that if you had spend half of the time
you spend at posting here, at improving one of the free Assemblers, it
would now be much better.

Now, if one wants to use TASM, i really do not understand why, but i
will not shot graves... Good for him.


Betov.
Posted on 2001-12-19 09:23:44 by Betov
the behaviour of SIZE depends of whether you're using 'Ideal' or 'MASM' mode. example:



.Data
SomeString db "This is a 29 character string",0

.Code
Ideal
mov eax,SIZE SomeString
MASM
mov eax,SIZE SomeString


this results in



401000 mov eax, 0000001Dh
401005 mov eax, 00000001h
Posted on 2001-12-19 09:41:19 by Tola
Thanks everyone!!!

I converted all my code in TASM's IDEAL mode...The SIZE actually worked, I thought it was a bug...

Now I know that when using SIZE in ideal mode(TASM) actually gives you the same behaviour as the SIZEOF in MASM. But when using SIZE in MASM it returns 1.

Though, in IDEAL mode you need an extra instruction for the window procedure(Nah!!! its only one line)

E.G.: mov eax, then compare...

:-)
Posted on 2001-12-19 11:24:54 by stryker
Though, in IDEAL mode you need an extra instruction for the window procedure(Nah!!! its only one line)

E.G.: mov eax, then compare...


you gotta change


cmp DWORD ptr [esp+4+4], 2h

into


cmp [DWORD ptr esp+4+4], 2h

for it to work in ideal mode (which i'm not using cause it'd be a major pain in the a** to convert the sources of my current projects ;))
Posted on 2001-12-19 14:37:46 by Tola