Introduction
How to crash TASM
Parsing problems / bugs
Remarks & advices
Conclusion
;just forget to put the right member ;) .if eax> ;.if ax>= ...
.data NICESTRUCT1 struct champ1 dd 0 champ2 dd 0 NICESTRUCT1 ends NICESTRUCT2 struct champ2 dd 0 champ3 dd 0 NICESTRUCT2 ends dummy1 NICESTRUCT1 <1,2>It will fail at compilation: Symbol already defined elsewhere: champ2
.data PRETTYSTRUCT struct field1 dw 0 field2 dd 0 PRETTYSTRUCT ends OTHERSTRUCT struct field3 db 0 field4 dd 0 field5 dd 0 OTHERSTRUCT ends dummy1 PRETTYSTRUCT <-1, -2> .code mov eax, dummy1.field5 ;dword ptr [dummy1+5] : will give eax=FFThat's the direct consequence the above problem (see Struct #1).
cmp 123h, dword ptr [esi] ;is not accepted (Illegal immediate) cmp dword ptr [esi], 123h ;is ok (left member: register or address)
lea eax, [1-ecx] ;TASM will understand: lea eax, [ecx-1]No error ! Remark: you can also try for many other instructions (push dword ptr [2-eax]).
.data .code main: int 3 call ExitProcess, NULL end mainResult: No .idata and no .reloc section !
extrn ExitProcess:PROC extrn CreateFileA:PROC extrn CloseHandle:PROC extrn ReadFile:PROC extrn WriteFile:PROC extrn SetFilePointer:PROC extrn MapViewOfFile:PROC extrn CreateFileMappingA:PROC extrn UnmapViewOfFile:PROC extrn SetEndOfFile:PROC extrn SetFilePointer:PROC ...The problem with extrn is that it won't be ignored if the api is not used. Used or not, your api will be written in the PE's import. The magic solution is to replace extrn with global. If the function (api) is used, (of course), it will be included in the import, otherwise i will be ignored ! Now you can make you own "mywin.inc" full of "global" and constant :) A little piece of my "monwin32.inc" :
global _wsprintfA : PROC ;"wsprintfA" (don't pop the args) global BeginPaint : PROC global BeginPath : PROC global BitBlt : PROC global CallWindowProcA : PROC global CheckDlgButton : PROC ;see BST_CHECKED, BST_INDETERMINATE, BST_UNCHECKED ...Of course, don't hesitate to add some equates, to make your life easier :
CreateFile equ <CreateFileA> CreateWindowEx equ <CreateWindowExA>
MessageBoxA PROCDESC WINAPI :DWORD,:DWORD,:DWORD,:DWORDRemark: MessageBoxA PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD is also accepted.
.code ;you have to way to call the api. ;first (the number of arg is checked) : call MessageBoxA, hwnd, offset sayhello, NULL, MB_OK ;second (the number of arg is not checked) : push MB_OK push NULL push offset sayhello push hwnd call MessageBoxAThis first case is the problem ! If you can you do for example:
.code .if (eax!=0) push MB_ICONEXCLAMATION .else push MB_ICONHAND .endif call MessageBoxA, hwnd, offset sayhello, NULLYou will obtain a Too few arguments to procedure error. That's on this point you can lose flexibility. So i prefer to declare each happy as :PROC (the number of args aren't checked but i think it's better).
BOOL TYPEDEF DWORD LPDWORD TYPEDEF PTR DWORD WPARAM TYPEDEF UINT LPARAM TYPEDEF DWORD HANDLE TYPEDEF DWORD HWND TYPEDEF DWORD HGLOBAL TYPEDEF DWORD HGDIOBJ TYPEDEF DWORD HACCEL TYPEDEF DWORD HBITMAP TYPEDEF DWORD HBRUSH TYPEDEF DWORD HDC TYPEDEF DWORD HFONT TYPEDEF DWORD HICON TYPEDEF DWORD HMENU TYPEDEF DWORD HINSTANCE TYPEDEF DWORD HRGN TYPEDEF DWORD HRSRC TYPEDEF DWORD HCURSOR TYPEDEF DWORD COLORREF TYPEDEF DWORD ...I really don't think it necessary (you can use it in some special case [like DirectX], don't focus too much on typedef). Beyond that, just think it's 32 bit. I do asm to be free ! For people loving typed stuff : code in C (LPARAM, WPARAM, HWND ; MAKEINTRESOURCE, (LPARAM)TEXT("48"), ..). That's my view. Just properly comment your asm source, there won't be any problem.
C:\TASM32
\Bin ;tasm32.exe, tasm.cfg, tlink32.exe, tlink32.cfg, brc32.exe, brcc32.exe, ...
\Include ;your include containing api and constant (monwin32.inc for me).
\Lib ;import32.lib (902k, contain fundamental DLL), but you can add other specific .lib like masm.
\Projects ;or another name, your projects will be located there.
My tasm.cfg contain: -ic:\tasm32\Include
My tlink32.cfg contain: -Lc:\tasm32\Lib
Consequently you won't need to declare many stuff, i simple line is enough !
MASM: include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\user32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib ... TASM: include mywin32.inc
@echo off c:\tasm32\bin\brc32 -r myprog1.rc c:\tasm32\bin\tasm32 -ml -m5 -q myprog1.asm c:\tasm32\bin\tlink32 -Tpe -aa -c -x -V4.0 myprog1.obj,myprog1.exe,,import32,,myprog1.res del myprog1.obj del myprog1.resRemark: Extensions are not indispensable (c:\tasm32\bin\tlink32 -Tpe -aa -c -x -V4.0 myprog1,myprog1,,import32,,myprog1).
@echo off c:\tasm32\bin\tasm32 -ml -m5 -q myprog2.asm c:\tasm32\bin\tlink32 -Tpe -aa -c -x myprog2.obj,myprog2.exe,,import32 del myprog2.objRemark: You can forget the output name myprog2.exe. (c:\tasm32\bin\tlink32 -Tpe -aa -x -c myprog2.obj,,,import32).
@echo off c:\tasm32\bin\tasm32 -ml -m5 -q myprog3.asm c:\tasm32\bin\tlink32 -Tpd -aa -c -x myprog3.obj,myprog3.dll,,import32,myprog3.def del myprog3.obj
+ : plus - : minus * : multiplication / : integer division MOD : modulus SHL : shifts x bits on the left SHR : shifts x bits on the right OR : bit or AND : bit and XOR : bit xor NOR : bit nor (a nor b = not(a or b) ) NAND : bit nand (a nand b = not(a and b) ) && : conditionnal and || : conditionnal or ^ : conditionnal xor EQ : (a EG b) gives 0 (if a!=b) and -1 (if a==b) GT : (a GT b) gives 0 (if a<=b) and -1 (if a>b) LT : (a LT b) gives 0 (if a>=b) and -1 (if a<b)Note: 4 bases are available:
mov eax, 11100b ;2 mov eax, 34o ;8 mov eax, 28d ;10 mov eax, 1Ch ;16
IFDEF WHATYOUWANT ;IFNDEF is available too ! ;... ENDIFOr, with the ELSE statement:
IFDEF WHATYOUWANT ;... ELSE ;... ENDIFTo define, just add this line inside your source (if you don't want to define it, comment the line):
WHATYOUWANT = 1 ;1 or any other number, equ works too.
.new SEGMENT 'NAMEINPE' ;if you don't specify any name, the name of the section will be 8 null chars. ENDSNote: The section will have C0000040 as characteristics.
IEEE Hex Format: dd 0.0 ;DWORD (4 bytes) dq 0.0 ;QWORD (8 bytes) dt 0.0 ;TBYTE (10 bytes)
mov wc.cbSize, Size WNDCLASSEXinstead of :
WNDCLASSEX_SIZE equ 4*12 mov wc.cbSize, WNDCLASSEX_SIZE
.data
TTEST struct
member dd 1
ends
x1 TTEST ?
x2 TTEST <?>
x3 TTEST <9>
x4 TTEST {}
x5 TTEST <>
.code
mov eax, x1.member ;0
mov eax, x2.member ;0
mov eax, x3.member ;9
mov eax, x4.member ;1
mov eax, x5.member ;1
Remark: That's very important to not affect values to struct members (use ? not 0). Otherwise you
won't be able to declare a struct in the .data? segment and you will get an error in union structs too. Example:
... HELLO struct f1 dd 0 ;should be "f1 dd ?" f2 dd 0 ;should be "f2 dd ?" HELLO ends ;you can simply put ends, but it's cleaner to put the name (same thing for procs) .data? aftertime HELLO <?>You will obtain a warning : Data or code written to uninitialized segment.
.data
SUPERHELLO struct
hello dd ?
union
bonjour dd ?
salut dd ?
ends
hiya dd ?
SUPERHELLO ends
iii SUPERHELLO <1,<2>,3> ;a common error is to put : "iii SUPERHELLO <1,2,3>"
;tasm reply: Need angle brackets for structure fill
.data
MYCOOLSTRUCT TABLE {
VIRTUAL field1 : dword
VIRTUAL field2 : dword
VIRTUAL field3 : word
VIRTUAL field4 : byte:16
VIRTUAL field5 : byte = 32h
}
abcd MYCOOLSTRUCT { field4 = "no order !", field2 = -2, field3 = 5, field1 = 1 }
.code
mov eax, abcd.field2 ;eax=-2
mov ecx, offset abcd.field4 ;(offset abcd + 10d)
movzx edx, abcd.field5 ;edx=32h
.data my_favorite_number dd 36157800d public my_favorite_number .code my_favorite_func proc ;compute: eax! public my_favorite_func push ebx ;(only ebx is modified) mov ebx,eax test ebx,ebx jnz recursif mov eax,1 pop ebx ret recursif: mov eax,ebx dec eax call my_favorite_func imul ebx pop ebx ret my_favorite_func endp end ;don't forget this ENDSecond and main file (program.asm):
.data
Externdef my_favorite_number : DWORD
Externdef my_favorite_func : PROC
.code
main:
;int 3
mov eax, my_favorite_number
and eax, 0Fh
call my_favorite_func
;...
call ExitProcess, 0
end main
How to compile (my make.bat):
@echo off c:\tasm32\bin\tasm32 -ml -m5 -q favorite.asm c:\tasm32\bin\tasm32 -ml -m5 -q program.asm c:\tasm32\bin\tlink32 -Tpe -aa -c -x -V4.0 program.obj+favorite.obj,Result.exe,,import32
Site Perso heberge par Anotherlight
:
Hébergeur |
|
| La solution hebergeur pour un hebergement de qualite. Decouvrer nos prestations d’ hébergement de site web. Nos formules incluent l’hebergement nom de domaine avec un support technique de qualite. l’hébergement mutualise est dédie aux professionnels et aux particuliers désirant un hebergement web fiable . Le depot de nom de domaine est inclus dans notre offre + plateforme d' hebergement php |