flat assembler
Message board for the users of flat assembler.
Index
> Tutorials and Examples > Code Construction questions for beginners |
Author |
|
BilboLaggins 29 Jan 2023, 17:36
Three questions using FAsm 1.73.29 with the attached source:
1. Why does the custom proc need to be before the _start:? To demonstrate the question, assemble and run to see the correct seven lines of output. Then move the proc to after the _start: by swapping the commented-status of lines 21 and 36. Assemble and run to see the wrong one line of output. What is happening? The design goal is to put the proc and its string definitions into their own Include-file, then assembled into their own OBJ for inclusion in a LIB. How is all that supposed to work relative to .data and .code sections? 2. Why does a standard proc like printf need square brackets "call [printf]" when a custom proc does not "call BoolPrint"? 3. What setup is necessary to allow invoke-ing a custom proc?
|
|||||||||||
29 Jan 2023, 17:36 |
|
Tomasz Grysztar 29 Jan 2023, 20:06
macomics wrote:
If you look at the INCLUDE/MACRO/PROC32.INC, where the "invoke" is defined, you may notice that there is also an "stdcall" macro that does the same thing, except it call the procedure directly, not through a pointer: Code: macro stdcall proc,[arg] ; directly call STDCALL procedure { common if ~ arg eq reverse pushd arg common end if call proc } macro invoke proc,[arg] ; indirectly call STDCALL procedure { common if ~ arg eq reverse pushd arg common end if call [proc] } Code: stdcall BoolPrint, argument Code: pBoolPrint dd BoolPrint Code: invoke pBoolPrint, argument Code: stdcall [pBoolPrint], argument |
|||
29 Jan 2023, 20:06 |
|
BilboLaggins 29 Jan 2023, 20:38
macomics wrote:
1a) [program execution begins immediately after] the _start label, [regardless of what code is there]. macomics wrote:
COFF for OBJ=>LIB yes that makes sense for step two. Sorry the question didn't match the code for step one: in case of moving the subroutine and its data strings out to an include file, does it matter where the include statement goes, like in the .data section versus in .code section? OR, would two separate includes and files be better? macomics wrote:
Thinking that even though printf at this level looks like a statically-linked proc say from a C library, programs which include 'Win32A.INC' make printf boil down to a WinAPI call, which are all dynamically-linked (it's how we can get a 2K EXE). Thus for Windows programs the real call-address is not known until program-load time, so the jump-table is totally necessary. In case of a program with actual static linking, does FAsm still use a jump-table, or is it able to resolve the real call-address at link-time, thus not needing a jump-table and allowing "call NoBrackets" for library routines? macomics wrote:
Thank you for taking the time to reply! |
|||
29 Jan 2023, 20:38 |
|
macomics 30 Jan 2023, 03:22
BilboLaggins wrote: 1a) [program execution begins immediately after] the _start label, [regardless of what code is there]. BilboLaggins wrote: Sorry the question didn't match the code for step one: in case of moving the subroutine and its data strings out to an include file, does it matter where the include statement goes, like in the .data section versus in .code section? OR, would two separate includes and files be better? When creating an OBJ file, there may be different sections in it and the linker collects them all together from all files. At the same time, you do not need various plug-in files. BilboLaggins wrote: Is that a reasonable way to understand it? BilboLaggins wrote: In case of a program with actual static linking, does FAsm still use a jump-table, or is it able to resolve the real call-address at link-time, thus not needing a jump-table and allowing "call NoBrackets" for library routines? Static linking when loading a file for execution is simply impossible because for different operating systems and on different computers there will be a different set of modules loaded into memory at the start of the program. Not to mention the fact that the base loading addresses of the same modules can change from version to version. Let's say in Windows XP the module kernel32.dll (I do not know how much it really weighs, this is just an example) It weighs 1 MB and is loaded at (2 GB - 1 MB = 0x7FE000000). But in Windows 7, the same module was supplemented with code, data and now occupies 1.5 MB (while its base load address changed and became (2 GB - 1.5 MB = 0x7FD800000)). In this case, the addresses of the functions from this module in the first case will be in the address range [0x7FE01000 - 0x7FFFFFFF], in the second - [0x7FD1000 - 0x7FFFFFFF]. All of the above is just an example. But he is not far from the truth and clearly (in numbers) should demonstrate the process of linking different modules when loading into memory. BilboLaggins wrote:
The author of fasm1 showed the full implementation of these macros in his answer Tomasz Grysztar wrote:
P. S. I didn't think about that when answering the last question. |
|||
30 Jan 2023, 03:22 |
|
edfed 30 Jan 2023, 15:00
Tomasz Grysztar wrote:
how can it becomes like: Code: macro stdcall proc,[arg] ; directly call STDCALL procedure { common if ~ arg eq reverse pushd arg common end if call proc } macro invoke proc,[arg] ; indirectly call STDCALL procedure { stdcall [proc],arg } this construct can help a lot to make heritage. |
|||
30 Jan 2023, 15:00 |
|
revolution 30 Jan 2023, 18:17
|
|||
30 Jan 2023, 18:17 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.