hello :),
i am interested in learning asm; i've realised that there are many assemblers out there such as masm, nasm, etc. i am wondering, would i have to learn a different style of coding for each assembler, because the sources that compile with each assembler seem to be different from each other.  As well, how would i be able to tell each source apart from which assembler they use?
Posted on 2006-04-22 18:43:45 by Macleon
Well, the instruction set remains the same no matter what assembler you use. However the availability of high level constructs, support for libraries, obj modules, structures, and the like will change. Many assemblers with "weak" symbol table algorithms require that you prefix operators such as constants (ie %WM_USER) while those with stronger symbol table algorithms can handle them without prefix. The best supported and fastest assembler today is probably either MASM or FASM, they are both exceedingly powerful and already support whatever you find you might need in the future. MASM easily has the most advanced macro system and the largest user base, probably multiples larger than all the others combined. For myself I prefer the lower level assemblers, particularly GoAsm which meets my needs quite nicely, library support, symbolic debugger, separate linker and 32/64 bit ready, not to mention it's free.

Another road to take is RosAsm which is a powerful assembler in it's own right and a completely integrated package. One of the major draw backs for me is that it is not possible to swap out a module that you are not satisfied with such as the editor, you are in all or nothing no substitutions. Also it does not have library support (last I heard) but has some very powerful tools that are supposed to adequately replace this deficiency. RosAsm has some very talented people who support it and though there is not a plethora of example code the list is growing daily. Lastly it is GPL, which may or may not be something you support, I will not comment on that.

For syntax, FASM is pretty much on it's own as is RosAsm, MASM and GoAsm are very close. Stay away from AT&T syntax, most of the GNU stuff uses that, it is difficult to decypher Intel manuals when you have to transpose half the things you read. You will quickly learn to jump from one to the other Intel syntax assemblers or at least translate between them.

Donkey
Posted on 2006-04-22 20:03:54 by donkey
oh ic that's interesting; if i were to use masm and come upon a source in tasm would it be challenging to change the format to masm because of the different libraries and libs? I am wondering how can i tell each source apart from which assembler they use?
Posted on 2006-04-23 20:21:05 by Macleon
GoAsm...

DlgProc FRAME hwnd,uMsg,wParam,lParam

MOV EAX,
.WMINITDIALOG
CMP EAX,WM_INITDIALOG
JNE >.WMGETDLGCODE
invoke GetDlgItem,,1001
invoke SetWindowLong,eax,GWL_WNDPROC,offset BtnSubClass
mov ,eax
JMP >.EXIT

.WMGETDLGCODE
CMP EAX,WM_GETDLGCODE
JNE >.WMCOMMAND
mov eax,DLGC_BUTTON
JMP >.EXIT


MASM

DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
mov eax,uMsg
.if eax==WM_COMMAND
mov eax,wParam
mov edx,eax
and eax,0FFFFh
shr edx,16
.if edx==BN_CLICKED
.if eax==IDCANCEL
invoke SendMessage,hWin,WM_CLOSE,0,0
.elseif eax==IDOK
invoke SendMessage,hWin,WM_CLOSE,0,0
.endif
.endif


TASM

PUBLIC DlgProcedure
DlgProcedure PROC STDCALL,hwnd_:DWORD,wmsg:DWORD,wparam_:DWORD,lparam_:DWORD
USES ebx, edi, esi

cmp     wmsg, WM_DESTROY
je     wmdestroy
cmp     wmsg, WM_CLOSE
je     wmdestroy
cmp     wmsg, WM_COMMAND
je     wmcommand
cmp     wmsg, WM_INITDIALOG
je     dlginit
xor     eax, eax
RET

wmdestroy:
call EndDialog, hwnd_, 0
call ExitProcess,0


FASM

proc DialogProc,hwnddlg,msg,wparam,lparam
enter
push ebx esi edi
cmp ,WM_INITDIALOG
je wminitdialog
cmp ,WM_COMMAND
je wmcommand
cmp ,WM_CLOSE
je wmclose
xor eax,eax
jmp finish
  wminitdialog:
jmp processed


NASM

@Dialog1Proc:   ;change to your name to this Dialog... or keep if you like the name.. :)

%define hdlg1 ebp+8 ;hwnd ... like this name better :)
%define dlg1msg ebp+12 ;wmsg ... like this name better :)
%define wparam ebp+16
%define lparam ebp+20

enter 0,0
cmp dword ,WM_INITDIALOG
je wminitdialog
cmp dword ,WM_COMMAND
je near wmcommand
;cmp dword ,WM_PAINT
;je near Paint
cmp dword ,WM_CLOSE
je near wmclose
jmp unhandled
Posted on 2006-04-23 21:00:36 by donkey
Just to make things fair here is a sample from NASM32. Note that the ButtonCtl macro is not a part of the Windows API rather one of the many CreateWindowEx wrappers I've put together into STDWIN.INC.


proc DlgProc, hwnd, umsg, wparam, lparam

switch dword argv(umsg)
case dword WM_CREATE
; ButtonCtl is a part of STDWIN.INC
ButtonCtl szString, 500, 0, 0, 100, 40, argv(hwnd),

case dword WM_COMMAND
if argv(wparam), EQUALS, dword 500
invoke MessageBoxA, dword NULL, dword szContent, dword szTitle, dword MB_OK
else
break
endif

case dword WM_DESTROY
invoke PostQuitMessage, dword NULL

default
invoke DefWindowProcA, dword argv(hwnd), dword argv(umsg), dword argv(wparam), dword argv(lparam)

endswitch
ret

endproc
Posted on 2006-04-23 23:45:01 by Synfire
Sorry Synfire,

I have never used or installed NASM, the only example code I have is the small app that comes with RadASM.
Posted on 2006-04-24 00:33:30 by donkey
donkey,
Yea, I understand. Truthfully, although I've designed the NASM32 macro's to extend HL features to look like the code in the previous post, I generally don't use such constructs very often.. my code usually looks more like:


PROC DlgProc
hwnd ARGD
umsg ARGD
wparam ARGD
lparam ARGD
mov EAX, dword argv(umsg)
cmp EAX, WM_CREATE
jz .wm_create
cmp EAX, WM_COMMAND
jz .wm_command
cmp EAX, WM_DESTROY
jz .wm_destroy

.default:
push dword argv(lparam)
push dword argv(wparam)
push dword argv(umsg)
push dword argv(hwnd)
INVOKE DefWindowProcA
...


I use PROC/ENDPROC so that I can use the argument features ARGD/ARGV. ARGD allows an optional argument which specifies byte, word, or dword (defaults to dword) unlike the style I showed below which forces all to dword. The INVOKE macro is a fairly complex one as it adds import entries for the procedure to the associated DLL when it's first called, so you don't have to have any .LIB files and you just need to include the required .INC files used.

Macleon,
Truth is, once you learn the instruction set, moving between assemblers is rather easy. The biggest difference is the preprocessors capabilities, and more often than not you can take what you know from one assembler and switch between assemblers within about a day or two of playing around with the preprocessor. I've personally used NASM for years, then a friend talked me into giving MASM a try. It took about 4 hours before I was comfortable with MASM's preprocessor and I really find it better for newcommers. NASM gets a bad wrap due to the complexity of it's preprocessor and that it's a weaker assembler in that it doesn't make any assumptions about sizes of arguments and makes you specify a lot of things yourself. Bottom line is, if you come up with your own way of using assembly that works with one assembler, you can be pretty sure that with a few small modifications that you will be able to port it to another. Only exception to that, is the difference between AT&T syntax and the "Intel" syntax that MASM, NASM, FASM, etc uses.. I quoted Intel because there really isn't an official Intel syntax and a few people on this board get touchy about that ;) But Assemblers like GAS, AS, and others which use the AT&T synax have a very different style and usually porting assembly code from one of those to something like MASM, NASM, etc usually calls for a complete rewrite. But as for MASM, NASM, FASM, GoASM, and others, there really isn't that big of a difference between them. Each have their ups and downs but they all more or less follow the same structure.

Regards,
Bryant Keller
Posted on 2006-04-24 03:46:15 by Synfire
Fortunately GAS supports .intel_syntax now, so even using that dinosaur should be relatively painless :)

Btw, FASM remembers the type/size of variables - so the following code snippet works without any overrides. BIG advantage over NASM, imo...


variable dd 10
mov , 100


also, mov , al will fail unless you use a "byte" override. Again, IMHO this is an advantage... you limit size overrides to where they're necessary (or give some safety), and remove the need to litter them all over.

That's just my personal opinion, of course.
Posted on 2006-04-24 04:05:19 by f0dder
f0dder,

I'm very suprised about GAS supporting .intel_syntax, mostly because the primary response from the developers when asking for features always something around the lines of, it's just for a compiler. I used GAS a long time ago while NASM was unavailable to me, so this is really amazing news to me :)

EDIT:
As for the "type casting" I agree, it is at times a pain in the rear (and more or less uncalled for), but once your used to it, there really isn't much of a problem. I actually thought of overriding mnemonics a for NASM32 but then figured it would be a lot of un-needed code. I feel if I was going to do that much work to change the language I would just start working on my own assembler (which I haven't completely thrown that idea out the window ;) )
Posted on 2006-04-24 20:23:46 by Synfire