Any code will be NASM, x86 arch tested on cygwin.
Personally I love macros and what spurred me to write this was my adventure today while I was remapping the PICs for my hobby O/S.
So what is a macro in assembly?
When the assembler encounters a macro label in your source code, it replaces the label with the text lines that the macro label represents. Also called 'expanding the macro'.
A macro definition is stored between a %macro and %endmacro directive.
Now after the %macro will be our label then followed by the number of parameters.Code:%macro ... %endmacro
So we named our macro 'mymult' and said it will take two parameters but how do we use these parameters?Code:%macro mymult 2 ... %endmacro
Basically this says to copy the first parameter or %1 into eax and copy the second parameter or %2 into ecx.Code:%macro mymult 2 mov ecx, %2 mov eax, %1 ... %endmacro
Pretty simple huh? Ok now for the rest of the code.
Cool now how do we call it? It's easy just use the label 'mymult', no need for a call.Code:%macro mymult 2 mov ecx, %2 mov eax, %1 dec ecx .loop: add eax, %1 dec ecx jnz .loop %endmacro
Another reason to use macro is when you have a bunch of similar pieces of code to write many times.Code:mymult 2, 4
Such as writing IRQs when remapping a PIC. If you don't understand the code itself don't worry just watch how I use macros to my advantage.
You'll notice there's only a few numbers that are changing.Code:global _irq0 _irq0: cli push byte 0 push byte 32 jmp irq_common_stub ;All the way to... global _irq15 _irq15: cli push byte 0 push byte 47 jmp irq_common_stub
So instead I just make a macro and let it do the work.
So when the assembler hits this for instanceCode:%macro Irq 2 global _irq%1 _irq%1: cli push byte 0 push byte %2 jmp irq_common_stub %endmacro Irq 0, 32 Irq 1, 33 Irq 2, 34 ... Irq 15, 47
It will turn it intoCode:Irq 0, 32
And it'll continue to do that for the rest of them.Code:global _irq0 _irq0: cli push byte 0 push byte 32 jmp irq_common_stub
So why do this? Why not just write a procedure? Well both ways have there pros and cons.
Macros are fast, there's no call or ret instruction the only instructions used are the one's actually doing work. However if there is a speed increase in code what does that usually tell us about memory?
Well let's say we have a macro that does 4 instructions and that macro is called 3 times. That's 12 instructions generated into memory.
+rep! Just because I'm anal-retentive, I have a few qualms about your mymul. What if the second operand is something large, like 80? I'll post a tutorial about multiplying and dividing so you'll know what I mean.
Last edited by dargueta; 03-18-2010 at 10:35 PM.
sudo rm -rf /
That piece of code wasn't written with the intention of being optimized in any way. I wrote it in my head with the intention of an easy to follow macro so a beginner can get his feet wet before moving into a real-world example.
I assumed you were just plugging for that other tutorial so I waited until you wrote it to post
Once I get some extra time I'll read over your post a bit more, assembly optimization is a favorite subject of mine eventhough it's possibly the broadest subject to ever conceive of mastering. I would argue impossible even.
I do appreciate the first paragraph explaining how cycle counting is insanely deceiving. Will read more later.
"The best optimizer is between your ears" - Michael Abrash
Saying you can optimize a program is like saying you understand how a program works on every level of every facet on a specific machines configuration.
Great tutorial, it's just that I'm...uh...optimizing is my cocaine...
I'm trying to kick it, I swear.![]()
sudo rm -rf /
There are currently 1 users browsing this thread. (0 members and 1 guests)
Bookmarks