flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > Macro tutorials Goto page 1, 2 Next |
Author |
|
scientica 29 Sep 2003, 04:45
Do you want tutorials about macros like this?
Code: macro sz name, [data]{ common label name forward db data common .size = $-name } _________________ ... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself. - Bradley Kuhn |
|||
29 Sep 2003, 04:45 |
|
Guest 29 Sep 2003, 07:25
Thanks Scientica for your answer.
Yes in this line, that is how should a beginner start writing macros, perhaps some explanations of what you have written, some possible pitfalls that might occur while writing the macros. This way from simple to more complex macro writing techniques/helps would be really nice. |
|||
29 Sep 2003, 07:25 |
|
scientica 29 Sep 2003, 12:43
Ok here is the explanation for it, let's hope I can explain it - If not just ask for a clarifiaction and I'll try my best to explain it in another way.
Code: macro sz name, [data]{ common label name forward db data common .size = $-name } This macro creates a string contauning the "data", and it "adds" an "local equate" (thing as in local label) with the name "size" which contains the size of the string. The data argument can basically be anythung that would be valid after a "db". The .size "member" is accessed by typing: name.size (where the name is the name you specify (the first argument to the macro)) Here are a few examples on what the output will be with different arguments Code: ;(in data section) sz szStringFooBar, "Foo Bar!",0 ;.. ;(in the code section) mov esi, szStringFooBar mov ecx, szStringFooBar.size ;--------------------------------------------------- ;This would give the same ouput as writing: szStringFooBar db "Foo Bar!",0 ;... mov esi, szStringFooBar mov ecx, 9 ; the size of the string is 9 ;--------------------------------------------------- ;one could also write: ;--------------------------------------------------- szStringFooBar db "Foo Bar!",0 .size = $ - szStringFooBar ;and then make use of: mov ecx, szStringFooBar.size Code: ;Here are a few more valid strings sz szString, "Hello Dword!",0 sz szString2, "Hello',9,'Dword!",13.10,'there is a tab between Hello and Dword, and this on a new line : )',0 sz szYAS, "YAS means Yet Another String",0 sz szJustSomeValues, 254, 75h,196,35,64h,35h,0 btw, I think that you should register, it's easier to remember a nick name rather then the Guest i Macroinstructions. And you're able to post in the other forums too. _________________ ... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself. - Bradley Kuhn |
|||
29 Sep 2003, 12:43 |
|
prana 29 Sep 2003, 17:28
Scientica, it's really great!
Btw my login screwed up a little, I managed to fix it. I am sure you can teach us some more tricks and techniques like this. Please keep posting and explain the topic with such examples. Thanks a lot! |
|||
29 Sep 2003, 17:28 |
|
prana 30 Sep 2003, 02:02
I'm having trouble to understand the following things, could some one kindly explain them with some examples and when to use them?
1) The difference btw '=' and 'equ' 2) The '.<var-name>' and '..<var-name>' 3) The 'forward', 'common', and 'reverse' - why they are required, and are there any other directives for macros? I'm really confused with this directives even though I've gone thru the manual. Pls explain a little. 4) The 'fix' directive 5) The '#','##', '@', '@@', and '%' symbols. Please help me! |
|||
30 Sep 2003, 02:02 |
|
scientica 30 Sep 2003, 05:46
Ok, I a little short on time - I'll try to give as many answers as I have time for right now.
1) the differece is that equ will replace the equate with the value. Here is an example Code: org 100h equate0 = $ equate1 equ $ mov eax, equate0 ; will result in 100h, since the value of $ was 100h at the time it was defined. org 200h mov ebx, equate1 ;will be the same as writing "mov ebx, $", since equate1 [b]equ[/b]als $ 2) '.<var-name>' are local labels, these are local to the previous label, for instance: Code: MasterLabel: ;... .sublabel: ; .sublabel can be referenced as .sublabel when you still are under the MasterLabel (if you define another global label) ; if you are under another global label you can still access the local label like this: SomeOtherMistressLabel: mov ebx, MasterLabel.sublabel Please note that declaring for instance a string will create a global label thus: MasterLabel: StringThis db 'String',0 .sublabel: ; typing MasterLabel.sublabel will yield an error, because there is no local by the name .sublabel under MasterLabel, but there is one under StringThis (named: StringThis.sublabel), if you put a "." before the StringThis then it'll be local and MasterLabel.sublabe will be legal. ; thus this is how it would look like: MasterLabel: .StringThis db 'String',0 .sublabel: 3) As I'm a little short on time I'll explain this later unless no one else replies bofre that. 4) The 'fix' directive is like equ, but it's processed among the first of all directives, try search teh boad for teh first thread containing fix. 5) From the manual Quote: It can be used to call indirectly (by the pointer stored in memory) the Code: The "@@" name means anonymous label, you can have defined many of them in the source. Symbol "@b" (or equivalent "@r") references the nearest preceding anonymous label, symbol "@f" references the nearest following anonymous label. These special symbol are case-insensitive. Code: 2.2.1 Repeating blocks of instructions "times" directive repeats one instruction specified number of times. It should be followed by numerical expression specifying number of repeats and the instruction to repeat (optionally colon can be used to separate number and instruction). When special symbol "%" is used inside the instruction, it is equal to the number of current repeat. For example "times 5 db %" will define five bytes with values 1, 2, 3, 4, 5. Recursive use of "times" directive is also allowed, so "times 3 times % db %" will define six bytes with values 1, 1, 2, 1, 2, 3. "repeat" directive repeats the whole block of instructions. It should be followed by numerical expression specifying number of repeats. Instructions to repeat are expected in next lines, ended with the "end repeat" directive, for example: repeat 8 mov byte [bx],% inc bx end repeat The generated code will store byte values from one to eight in the memory addressed by BX register. Number of repeats can be zero, in that case the instructions are not assembled at all. G2G School now, bye _________________ ... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself. - Bradley Kuhn |
|||
30 Sep 2003, 05:46 |
|
prana 30 Sep 2003, 07:16
Thanks a lot!
Pls keep posted. |
|||
30 Sep 2003, 07:16 |
|
scientica 30 Sep 2003, 15:17
prana wrote: 3) The 'forward', 'common', and 'reverse' - why they are required, and are there any other directives for macros? I'm really confused with this directives even though I've gone thru the manual. Pls explain a little. 3) Ok, you've read the manual, first: don't panic (), but let's take a look at the docs first: (It's not as much reading as it seems). Second: panic!!! Code: If after the "macro" directive you enclose some group of arguments' names in square brackets, it will allow giving more values for this group of arguments when using that macroinstruction. Any more argument given after the last argument of such group will begin the new group and will become the first argument of it. That's why after closing the square bracket no more argument names can follow. The contents of macroinstruction will be processed for each such group of arguments separately. The simplest example is to enclose one argument name in square brackets: macro stoschar [char] { mov al,char stosb } This macroinstruction accepts unlimited number of arguments, and each one will be processed into these two instructions separately. For example "stoschar 1,2,3" will be assembled as the following instructions: mov al,1 stosb mov al,2 stosb mov al,3 stosb ...... "forward", "reverse" and "common" directives divide macroinstruction into blocks, each one processed after the processing of previous is finished. They differ in behavior only if macroinstruction allows multiple groups of arguments. Block of instructions that follows "forward" directive is processed for each group of arguments, from first to last - exactly like the default block (not preceded by any of these directives). Block that follows "reverse" directive is processed for each group of argument in reverse order - from last to first. Block that follows "common" directive is processed only once, commonly for all groups of arguments. Local name defined in one of the blocks is available in all the following blocks when processing the same group of arguments as when it was defined, and when it is defined in common block it is available in all the following blocks not depending on which group of arguments is processed. The first macro showed is this: Code: macro stoschar [char] { mov al,char stosb } It could be written as: Code: macro stoschar [char] { forward mov al,char stosb } what forward does is that for each argument in char (in the example [char] is three arguments: 1, 2 and 3) is perfomes the code untill either: 1) The macro end. 2) forward, reverse or common is encountered. The revese does the same as forward, but it starts with the last argument in [char]. Code: macro stoschar [char] { reverse mov al,char stosb } stoschar 1,2,3 ;above would be assembled as: mov al,3 stosb mov al,2 stosb mov al,1 stosb common is only processed one, where as forward and common is processed for every argument in [char]. Here is another example from the docs: Code: macro stdcall proc,[arg] { reverse push arg common call proc } ;can also be written as: macro stdcall proc,[arg] { reverse push arg common call proc } stdcall AnyProc, 1,2,3 What happens here is: First, for every argument in [arg] starting with the last argument do this: "push arg" (where arg is the "current" argument in [arg], in the first "pass" in the macro arg will be 3, in the second "pass" arg will be 2, and in the last it will be 1). Then, do this (once): "call proc" (where proc will be equal to AnyProc). So in short, "stdcall AnyProc, 1,2,3" it will compile as: Code: push 3 push 2 push 1 call AnyProc I attach an example file, it contains an example of the use of [var] but with one difference, take a look and see (btw, compile the file with this command: "fasm test.asm tmp.htm" and open it in a web browser) _________________ ... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself. - Bradley Kuhn |
|||
30 Sep 2003, 15:17 |
|
prana 01 Oct 2003, 01:37
scientica, this is just great
Your last post cleared up a lot of confusion I had Just one question, why the "..<var-name>" is used? Also to the moderator/s of this board, I'm sometimes unable to see attchments posted with messages Why so? As for now I'm unable to see the test.asm that scientica has posted. I'm using IE 6. Thanks scientica, also pls keep us posted with new lessons. Thanks a lot |
|||
01 Oct 2003, 01:37 |
|
scientica 01 Oct 2003, 04:25
-- I'm not sure I can post - but if you can read this I could --
The file test.asm isn't attached in the posts (when I posted I got debug mode error and (doublepost)^2+1 and the file didn't want to come up), but I've made a raw copy and attached the file on the other forum board.win32asmcommunity.net. Btw I could delete the doubleposts after "a few" attepts to deltre them (using the "x" button) I'll try to answer that later to day (soon time for shcool (where I'm up for a 5 hour math competition -- I've chosen it my slef, am I mad? Yes ) then tonight there is yet another competition I'm in for ). But mean while you can try to search teh other forum (I think the issue is explained there) _________________ ... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself. - Bradley Kuhn |
|||
01 Oct 2003, 04:25 |
|
prana 01 Oct 2003, 04:32
Well I'll try to grab that file from board.win32asmcommunity.net.
Just two questions now: 1) why the "..<var-name>" is used? 2) how can I get an interim look of my source file with all macros expanded? Please help. In btw, all the best for your competition |
|||
01 Oct 2003, 04:32 |
|
scientica 01 Oct 2003, 15:01
prana wrote: Well I'll try to grab that file from board.win32asmcommunity.net. 1) To tell the truth I had forgotten the maeing of the ..labels :oop: , but I knew there was an thread about somewhere, here it is: "What are ..variables?" - http://board.win32asmcommunity.net/showthread.php?s=&threadid=6956&highlight 2) Don't know, but I remember seeing a post (on this board) with a listing version of fasm - seach for it. by the way, first competition done (the 5 hour math competition (Don't know exactly when I get to know how bad () it went )) one more to go in a few hours time. _________________ ... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself. - Bradley Kuhn |
|||
01 Oct 2003, 15:01 |
|
prana 01 Oct 2003, 16:55
Thanks for the thread friend
However still searching for the listing feature of fasm - does it produce a .lst file? In btw, congrats for finishing the first competition, carry on |
|||
01 Oct 2003, 16:55 |
|
scientica 01 Oct 2003, 18:25
Here is the thread I'm speaking of: http://board.flatassembler.net/topic.php?t=213&highlight=listing
btw, in a few hours I should have the result for the last competition. _________________ ... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself. - Bradley Kuhn |
|||
01 Oct 2003, 18:25 |
|
prana 02 Oct 2003, 08:17
Thanks for the link pal
However, pls keep us posted with any new techniques you invent For some time I'll be busy writing macros now And any idea when Privalov will finish the tutorial? I can hardly wait for it! Btw, how was your score? Must be a good news, all the best |
|||
02 Oct 2003, 08:17 |
|
scientica 02 Oct 2003, 14:41
I still haven't gotten any info on the first competition, the second however, well the class which I competed with (my kid brothers class), unfortainly we didn't score enought points to be in the top 3 (don't know exactly in what place we ended up in).
Perhaps the WinStyle (in styleeditor.asm of the Fresh project) macro would be of interest? (I'll explain it later, must do some homework first.) _________________ ... a professor saying: "use this proprietary software to learn computer science" is the same as English professor handing you a copy of Shakespeare and saying: "use this book to learn Shakespeare without opening the book itself. - Bradley Kuhn |
|||
02 Oct 2003, 14:41 |
|
Tomasz Grysztar 03 Oct 2003, 13:32
Thanks for your work scientica! You was faster than me, I was also planning to make some tutorial about writing macroinstructions, but I managed only to finish the introduction about symbolic constants. I'm posting it here - if you find it useful, I may write more about using symbolic constants in macros, and then about using the "fix" variant - but those should be later parts, as we can use your work as the "part 2" of this tutorial.
Part 1 - Symbolic constants Symbolic constants are those defined with "equ" keyword - in opposite to those defined with the "=" operator, which are called the numerical constants. Numerical constants are just a special variant of labels, which have assigned some value (absolute, or some relative address) and can be used in the numerical expressions. Any numerical expression is calculated by assembler each time it has to generate the code for instruction containing that expression, as the values of labels and numerical constants may very between the assembly passes. The only difference between regular label and numerical constant is that the constant can be redefined (but when it is redefined at least once in the source, it cannot be back-referenced). Symbolic constants are completely different - they can have any value, not necessarily a numerical expression, and they are replaced with that value everywhere in source starting from the line following the one containing the "equ" definition. It is done by preprocessor, and only such source goes to the main assembler module (it is also processed by the parser module in the meantime, but that's another story). Let's see on small example how does it work and how does it differ from numerical constant processing. Look at the following two definitions: Code: symbolic equ $
numerical = $ The dollar sign is the special symbol that in numerical expressions is interpreted as the value of current address in output code. So when we define numerical constant with the value of that expression, it will be just equal to the address of the point in code, where it was defined. Each time assembler sees that constant in some expression, it will calculate the final value using that address. But the symbolic constant will be just replaced with the dollar sign everywhere it occurs later in the source, so the assembler will see just the dollar sign in every place we use this constant, and will calculate the value using the current address. For example, if we put the above definition at the beginning of source (with binary output), the "numerical" will have value of 0, so the following instructions: Code: db numerical db numerical both define the zero byte. But if instead we wrote this: Code: db symbolic db symbolic these instruction will be seen by assembler as: Code: db $ db $ And so the first one defines the zero byte, but the second one defines byte of value 1. To finally punctuate the difference between symbolic and numerical constants, I'll provide one more example in this context: Code: dd symbolic+numerical will be seen by assembler as: Code: dd $+numerical The numerical constants are never replaced with anything - their values are only used in the calculations. And the definitions of numerical constants are interpreted at assembly time, while symbolic constants are already processed at this stage, and their definitions are no longer visible. Numerical constants are recommended for the purpose of defining any equates, as they are usually processed faster. The symbolic constants may be useful for more complex applications, like various syntax adjustments, for example defining some shortcuts: Code: b equ byte w equ word d equ dword With such definitions we can then use single letter operators to specify the size of operand in assembly instruction. Any symbolic constant can be redefined, in such case its name is not replaced with its value, but all symbolic constants after the "equ" operator are processed normally. Therefore such two definitions: Code: symbolic equ $ symbolic equ symbolic+1 will leave us with constant having value "$+1". There is also the "restore" directive that allows us to get back the value of symbolic constant that was redefined. For example if after the two lines from the example above we put the following: Code: restore symbolic we will get back the value "$" assigned to that constant. If we repeat it, it will get back the initial meaning, so "symbolic" word won't be anymore replaced with anything other. As you can see, symbolic constants in arguments for the "restore" directive are not replaced with their values, as in the above example we would get the "restore $+1" instruction, which makes no sense. This rule applies to all the directives interpreted by preprocessor - they are immune to the symbolic constant processing, and the "restore" is one of them. |
|||
03 Oct 2003, 13:32 |
|
prana 03 Oct 2003, 16:46
It's just great
Can hardly wait for the next part I'm compiling all work of yours in this thread |
|||
03 Oct 2003, 16:46 |
|
LiuGuoHua(Chinese) 27 Oct 2003, 06:19
Really nice work!
I'm attemping to translate it into Chinese. Keep on, waitting! |
|||
27 Oct 2003, 06:19 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.