I have been very lax about sharing my experiences with the advanced assembly course, and ill tell you why – I am actually having a tough time and its bothering me. Its not tough to accomplish the projects…
- Write an app that calculates the GCD for two integers
- Begin work on my own Strings and Output libraries
- Continue work on libraries, work with FileIO
- Floating point arithmetic & stack manipulation
Overall it has been a lot of fun, learning about the memory interaction and trying to find better ways to work with arrays and heap allocation etc. It is definitely not as simple as some would have it be, but… fun is definitely an appropriate label:
This class is focused on getting beyond the Kip Irvine library and learning about the Windows API, Floating point arithmetic, and memory management. The most recent two labs have been incredibly telling, particularly about the Windows API, and for the record – I don’t like it.
.data sysTime SYSTEMTIME .code INVOKE GetLocalTime, ADDR sysTime xor eax,eax mov AX, sysTime.wMonthcall
This block of code will grab and put the current month into AX, and there is something incredibly funny that goes on. In every other language that I have used to grab the current date (PHP, Ruby, Perl, C++, etc.) the date is one less than what we expect it to be. In assembly this call is exactly what you expect it to be…
|Month||Typical Return||Assembly Return|
When i found this out i was incredibly confused, but this is really only the tip of the iceberg, but ill move on to some more interesting tid-bits.
Assembly has structures, in a similar format to C, only now we are aware of memory alignment. Saving every memory call we can is the point of moving to Assembly. We can surely do all of this in higher level languages and completely ignore what is going on under the hood. So as you could imagine, we have had quite a bit of competition in our class. In our most recent lab we had a lot to handle. File handles, IO and Dynamic Memory Allocation. I may even get the time and energy together to rerelease my OBJ converter in ASM. I have to say though, memory allocation can be very fun.
Here is something important that I would like to share. Assembly provides a number of tools to keep your development clean. We are adhering to the STDCALL format of procedure writing, which translates to “clean up after your self” and is set at odds with the C style which translates to “caller cleans up after you.” With our standards, our procedures should leave all registers, flags and memory pretty well as it stands, unless I’m returning a value on the stack or in EAX.
One such tool is the USES statement, and it is followed by a list of all registers you are using in your procedure. For instance, if this is the abstraction of my equivalence to Malloc in C. You pass it a length you need in bytes, and it will grab it from the heap. Note that im only using EAX, but i mention EDX and ECX.
Allocate PROC USES EAX ECX EDX, iLength:DWORD INVOKE HeapAlloc, hHeap, HEAP_ZERO_MEMORY, iLength mov [EBP + 12], EAX ret Allocate ENDP
This is the second issue with the Windows API, the calls dont preserve the registers. STDCALL allows you, as the developer, to focus on the development and not bother with screwing with the stack every other line. I’m sure that there are solutions outside of that, but its the reasoning i have found.
I also did the following procedure to simplify string copying. You pass it the source, destination, and length of the destination buffer.
CopyString PROC USES EAX EDI ESI ECX, Source:PTR BYTE, Destination:PTR BYTE, iLength:DWORD mov EDI, Destination mov ESI, Source mov ECX, iLength mov EAX, Destination sub ECX, 3 add EAX, ECX mov BYTE PTR [EAX], 0dh inc EAX mov BYTE PTR [EAX], 0ah NEXT: movsb LOOPZ NEXT ret CopyString ENDP
As you can see, registes are still where its at. I use the heap’s Zeroing to put a 0 at the end, and my strings are 0 delimited so i allocate +3 for the rn characters.