I set myself the task of writing an asembler program to run on a mobile phone that transforms an audio wave file into a frequency spectrum and in order to determine the frequency in Hz of a generated tone. This is done using pure assembler code and not using any third-party FFT algorithms. The program is to run inside a Debian-like terminal application called Termux on mhy phone.
I might point out that I have had a long background in computer engineering but now retired. These days I program as a hobby.
Because I initially had some experience with early FASM way back in 2002 I decided to go back to FASM as my choice of assembler and began developing my project as x86 code on an x86 AMD Chromebook laptop. After a point in the development I tried to manually transcribe the x86 code into ARMv8 64 bit code on my phone using the GNU assembler (Binutils with as and ld as assembler and linker) inside the Termux application. That experience gave me some practice using mainstram ARM code but the difficulty was using a tiny phone, with the tiny screen and keypad, to manually code with.
I then looked for a way to develop code on my laptop computer but deploy on my phone. That is when I discovered FASMARM which seemed to be promising because it could solve the program development/deployment problem, and because I could leverage my experience with FASM. The next problem was that rapid deployment of trials and tests while developing was impractical because I would need to copy each testing iteration to the phone every time.
Then I discovered QEMU, which is program that enables the AMD laptop device to emulate ARM code. Now it is possible to develop the program and rapidly test how things are going completely on the laptop. Only after being reasonable sure about the final product I would then transfer the program to the phone. Of course I realised that I could also use the GNU asembler on the laptop and also use QEMU for testing, but since I was now familiar with FASMARM I decided to stick with it.
I now also had a chance to compare FASMARM with the more mainstream ARM/GNU assembler. The differences were only minor and were with the directives, the way data is defined, with comment syntax and with the syntax used to load an address to a register. The instrunction syntax is essentially the same. There is really basically not much difference but sticking in the FASM realm seemed a cool thing to do.
My method of coding depends a lot on using my own common reusable labelled "subroutines" in a separate include file. I use a few macros only for very commonly used short routines. However, in the ARM 64 bit world, returning from nesting more than one level of branch and link calls will result in execution failure because return addresses are not shuffled into a stack as in x86 programming. I got around this problem by using a section of memory for my own tiny "stack" and wrote my own push and a pull macros to remember and restore the various levels of return adresses. Another problem I encountered was not being successful in deploying FP maths in ARM. OK for the FASM 1 version but for the ARM code I resorted to the trick of multiplying input data by 10 or 100, using normal integer maths, and then poking in a decimal point appropriately for the final display output. Call it cheating but it works and may be more efficient.
Thankyou Tomasz, and revolution, for providing this package. This has given me a great deal of joy (ignoring the many little frustrations when things don't work first go!) Now it's time to keep refining my product.
|