A Horrible Conversion from Binary to Decimal in (ARM64) Assembly

This is not my finest code. It is the worst case of “just make it work” I’ve produced all week.

But it runs.

What does it do? It takes the first binary number in an array, and converts it to decimal. It assumes that the number is no more than 3 digits long.

It divides that number by 100 to get the 100s digit. Then it multiples that number by 100, assuming that it has gotten truncated. It subtracts that value from the original number to chop off the 100s digit, and divides the result by 10 to get the 10s digit.

Continue reading

Changing the Output in (ARM64) Assembly

When ever I write new console based code from scratch, I start with “Hello World.” Then I make one small change at a time, test it, and commit. Then I move on. While this slow process might seem tedious, it is based on years of wasting time debugging my own poorly written code in interim changes.

Once I had “Hello, World!” working in assembly, I want to make a single character change to message and see it in the console. Here’s my steps.

Continue reading

Simplest (ARM64) Assembly Program that Runs without an error

In order for a program to run successfully, it needs two things: an entry symbol, and a return code that represents that success. The following program provides those two things.

.global _start
 
_start:     
            MOV     X0, #0
            MOV     X8, #93
            SVC     0

Compile it using the simple Makefile from the previous article.

The symbol _start is a special symbol expected by the linker. If you try to rename like this…….

.global _ADAM
 
_ADAM:     
            MOV     X0, #0
            MOV     X8, #93
            SVC     0

…you get the following error:

$ make other
as -o other.o other.s
ld -o other other.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400078

Which will still compile and run.

If you leave off the three assembly instructions at the end, you do not return 0 indicating the program success.

.global _start
 
_start:

That gives you this error:

]$ ./bad_return -bash: ./bad_return: cannot execute binary file: Exec format error

To be honest, there are no instruction in the code, and I think that is a different problem. If we skip executing the function to send the return code:

.global _start
 
_start:     
            MOV     X0, #0
            MOV     X8, #93

That gives this error when run:

$ ./bad_return 
Illegal instruction (core dumped)

Simple Makefile for assembly executables

I want to automatically build assembly files into executable binaries. The following Makefile seems to be sufficient. I am sure I will add to it over time.

All I have to modify is the SRC_FILES line to add a new target

Note that html does not honor the tab characters.

EDIT: I swapped the SRC_ and B_ files so that the top list is the end result. This allows you to just run make and build all of your executables. It would also let you mix and match between assembly and other languages. But (most importantly) I like it better.

B_FILES=simple printer
SRC_FILES = $(B_FILES:%=%.s)
O_FILES = $(SRC_FILES:%.s=%.o)
 
all: $(B_FILES) 
 
%: %.s 
	as -o $@.o $<
	ld -o $@ $@.o
 
clean:
	rm -f $(O_FILES) $(B_FILES)