Explain the difference between assemblers and MASM FASM. Yurov studying a book with practical algorithms in assembly language, and decided to write them on the FASM, because they say it gives more opportunities. The first thing that did not like – an extra import section with garbage inside, without which I treated before, and the need to put the byte ptr where in MASM not required. FASM seems excessive.
Finally, a simple example from the book fulfills very strange:
format PE Console 4.0 entry start include 'win32a.inc' section '.text' code readable executable start: call add_uint proc add_uint mov al, byte ptr a add al, 10 jnc end_p adc byte ptr carry, 0 end_p: ret endp exit: invoke ExitProcess, 0 section '.data' data readable writeable a db 255 b db 7 sum db 0 carry db 0 section '.idata' import data readable writeable library kernel, 'kernel32.dll' import kernel, ExitProcess, 'ExitProcess'
The debugger shows that after the ret in the procedure, we find ourselves again in the beginning of the procedure, it works off a second time, and only then proceed to the return address. Why is it so?
Answer 1, Authority 100%
The first thing that did not like – an extra import section with debris inside the
When I see questions on MASM, almost all of them have a bunch of junk
include . One change to another. On fasm can be written without explicitly specifying the import section, unless, of course, you do not need to call functions from libraries outside the “standard”.
hello.asm from fasm package, as you can see, nothing “superfluous”:
format PE GUI 4.0 ; example of simplified Windows programming using complex macro features include 'win32ax.inc'; you can simply switch between win32ax, win32wx, win64ax and win64wx here .code start: invoke MessageBox, HWND_DESKTOP, "Hi! I'm the example program!", invoke GetCommandLine, MB_OK invoke ExitProcess, 0 .end start
the need to put the byte ptr where in MASM this was not required.
It is best to put square brackets, then the size will not have to be explicit. In your case, appeal to the variables can be changed to a:
mov al, [a] ... adc [carry], 0
If the call goes to the entire variable, the “size” is not needed (size determined by the size of the variable). If there is an appeal, for example, one byte of dword variable size, you need to specify the byte size:
mov al, byte [a] ... a dd 255
Address by some address in fasm denoted by the name of a variable or register in brackets. I think it is more logical than the way it is done in MASM dialect (if the address in the register – the brackets, if the address is in the variable – without them)
The details why it was decided to do so, see. In Design Principles (or why flat assembler is different?)
Just displacement (offset) is referred to as a variable name without brackets, ie
mov eax, offset a in the dialect fasm will look like
mov eax, a .
Finally, a simple example from the book fulfills a very strange
Of course, will be enough to work, if you put the function immediately after the call. processor code is carried out linearly (yet he does not meet the control transfer instruction) . Naturally, the return call after the processor encounters a function of who had just returned, and starts to perform it again.
If it is simplified, then the code of the function itself must be installed outside the code of other functions (above or below, it does not matter), or do
EXIT immediately after
Call , since you started such a label, then “excess” execution of the
add_uint function will not be.
This is not the specificity of FASM, the same code for MASM will be performed the same.
And finally, the working example code for FASM. Please note that another file is connected via
Include , which allows you not to specify the import section explicitly (the import section will actually be added by the
Format PE CONSOLE 4.0 include 'win32ax.inc' .code. Proc Add_Uint. MOV AL, [A] Add Al, 10 JNC END_P. ADC [CARRY], 0 end_p: RET. Endp. Start: call add_uint INVOKE EXITPROCESS, 0 .data. A DB 255. B DB 7. SUM DB 0. CARRY DB 0. .end start