📜 ⬆️ ⬇️

We write an Android application in assembler

image

This story is about a non-standard approach to the development of Android applications. It's one thing to install Android Studio and write “Hello, World” in Java or Kotlin. But I will show how this same task can be accomplished differently.

We remind: for all readers of "Habr" - a discount of 10,000 rubles when recording for any Skillbox course on the promotional code "Habr".

Skillbox recommends: Online Profession Java Developer Educational Course.
')

How does my smartphone work with Android OS?


First, a little background. One evening a friend called me named Ariella. She asked me: “Listen, how does my smartphone work? What's inside? How do electrical energy and ordinary ones and zeros allow all this to function? ”

My friend is not a noob in development, she created several projects on Arduino, which consisted of both software and hardware parts. Maybe that's why she wanted to know more. I was able to answer with the help of knowledge gained in one of the computer science courses at the university.

Then we worked a couple of weeks together, because Ariella wanted to find out how the electronics building blocks, that is, semiconductor elements, including transistors, work. Then we went to a higher level: I showed her how to create logic gates, for example, NAND (logical AND) plus NOR (logical OR) using a specific combination of transistors.

We investigated the logical elements of different types, combined them to perform calculations (for example, adding two binary numbers) and memory cells (triggers). When everything cleared up, they began to develop a simple processor (imaginary), in which there were two general registers and two simple instructions (adding these registers). We even wrote a simple program that multiplies these two numbers.

By the way, if you are interested in this topic, then read the instructions for creating an 8-bit computer from scratch. It explains almost everything from the very basics. I wish I could read this before!

Hello, Android!


After completing all the stages of the study, it seemed to me that Ariella had enough knowledge to understand how the processor of the smartphone works. Her smartphone is the Galaxy S6 Edge, whose base is the ARM architecture (as is the case with most smartphones). We decided to write a “Hello, World” application for Android, but in assembly language.

.text .globl _start _start: mov %r0, $1 // file descriptor number 1 (stdout) ldr %r1, =message mov %r2, $message_len mov %r7, $4 // syscall 4 (write) swi $0 mov %r0, $0 // exit status 0 (ok) mov %r7, $1 // syscall 1 (exit) swi $0 .data message: .ascii "Hello, World\n" message_len = . - message 

If you have never come across an assembler code before, then this block may scare you. But do not worry, let's sort the code together.

So, our program consists of two parts. The first is text with machine code instructions, and the second is variables, strings, and other information (starting at line 15). The .text section is usually available only for reading, and .data is also available for writing.

In line 2, we define a global function called _start. It represents the entry point to the application. OS starts to execute code from this point. The function definition is declared in line 4.

In addition, the function performs two more things. In lines 5–9 the message is displayed on the screen, in lines 11–13 the program ends. Even if you delete lines 11–13, the program will print our “Hello, World” line and end. However, the output will not be correct, because the program will end with an error. Without lines 11–13, the application will attempt to execute an invalid instruction.

The print is displayed using the system function “System Call” of the operating system. In the application, we call the write () function. We specify it when we load the value 4 into the processor register with the name r7 (line 8). Next, the instruction swi $ = 0 (line 9) is executed, where the transition goes directly to the Linux kernel, which is the basis of Android.

As for the parameters for the system call, they are transmitted through other registers. For example, r0 shows the file descriptor number we need to print. We put there the value 1 (line 5), indicating the standard output (stdout), that is, the output to the screen.

r1 points to the memory address of the data we want to write, so we simply load the address of the string “Hello, World” (line 6) into this area, and the register r2 shows how many bytes we want to write. In our program, it is set to message_len (line 7), calculated in line 18 using a special syntax: the dot character indicates the current memory address. For this reason. - message denotes the current memory address minus the message address. Well, since we declare message_len immediately after a message, all of this is calculated as the length of the message.

If you write the code of lines 5–9 using C, you get the following:

 #define message "Hello, World\n" write(1, message, strlen(message)); 

Quit the program a little easier. To do this, we simply write the exit code to the register r0 (line 11), then add the value 1, which is the call number of the system function exit (), to r7 (line 12), then call the kernel (line 13) again.

A complete list of Android system calls and their numbers can be found in the source code of the operating system . There is also a write () and exit () implementation that calls the corresponding system functions.

We collect the program


In order to compile our project, you need an Android NDK (Native Development Kit). It contains a set of compilers and build tools for the ARM platform. You can download it from the official site, install it - for example, via Android Studio.



After the NDK is installed, we need the arm-linux-andabeabi-as file, which is an assembler for ARM. If you downloaded via Android Studio, then look for it in the Android SDK folder. Usually its location is

ndk-bundle \ toolchains \ arm-linux-androideabi-4.9 \ prebuilt \ windows-x86_64 \ bin.

After the assembler is found, save it in a file called hello.s, then run the following command to convert it to machine code:

arm-linux-androideabi-as -o hello.o hello.s

This operation allows you to create an object ELF file named hello.o. In order to convert it to a binary file that can work on your device, call the linker:

arm-linux-androideabi-ld -o hello hello.o

Now we have a hello file that contains a program that is completely ready for use.

Run the application on your device


Android applications are usually distributed in .apk-format. This is a special kind of compressed file that includes Java classes (yes, you can write with C / C ++, but the entry point should be Java).

In order to avoid problems when launching the application, adb was used in the example, which allowed copying it to a temporary folder of our Android device. After that, we launch adb shell in order to start the application and evaluate the result:

adb push hello / data / local / tmp / hello
adb shell chmod + x / data / local / tmp / hello

And finally, run the application:

adb shell / data / local / tmp / hello

And what do you write?


You now have a working environment similar to the one that Ariella had. She spent a few days studying the ARM-assembler, then came up with a simple project - this is the game Sven Boom (a Fizz Buzz variety originally from Israel). Players count in turn and each time the number is divided by 7 or contains the number 7, they must say “boom” (hence the name of the game).

It is worth noting that the program for the game is not such an easy task. Ariella wrote a whole method that displays numbers, one digit at a time. Since she wrote everything in assembler without calling the standard functions of the C library, she had to spend several days on the solution.

Ariella's first program for Adnroid is posted right here . By the way, some code identifiers in the application are actually Hebrew words (for example, _sifra_ahrona).

Writing an Android application in assembler is a good way to get acquainted with the ARM architecture, as well as better understand the internal kitchen of the gadget you use every day. I invite you to do this closely and try to create a small application in assembly language for your device. It could be a simple game or something else.

Skillbox recommends:

Source: https://habr.com/ru/post/441798/


All Articles