I decided a long time ago to get acquainted with the architecture assembler Arm. Mostly to familiarize and understand the internal processes of architecture. The more I studied literature and various sources, the more I realized that practice was needed. I decided to remember the assembler for x86-x cars and at the same time practice on architecture Arm.
But as always, to practice you need to be prepared, and as it turned out, I was not prepared…
Memo. For code test I use Linux. More precisely, if you Windows then you will need to use WSL or virtual machine. And if you have Macthat is, there is a possibility that you will be able to do everything exactly the same as on Linux. Can’t you? Don’t worry, just create a virtual machine Linux.
First we had to decide on the choice of assembler. The choice of assemblers is quite large: Masm, Nasm, Yasm, Fasm, Gas and others. I needed an assembler that would be used in architecture x86 create code for any platform. And I settled on assembler Gas, for the reason that it was the only assembler that satisfied my conditions. But at the moment, as can be seen from forum updates, Fasm also began to support architecture Arm64 (before this there were errors with compilation for this architecture). But still I will use Gasbecause I have long been prepared to develop in this assembler.
But you can try too Fasm. )))
This is a video with general information, there is no code in it. The video was made a long time ago, please don’t throw tomatoes.
https://youtu.be/Wk4o7OjXmEw – link just in case, someone doesn’t want to load anything without a VPN…
We will not use any emulators, except for emulators that will execute our code under our architecture. These will be emulators from Qemu: qemu-arm And qemu-aarch64. These emulators will only be able to execute code on the command line, so don’t expect to be able to execute code for any graphical window. This is quite suitable for code tests. By the way, these files may be in the Android SDK (or NDK?), but I could be wrong.
Here I post all the code, and two emulators, which I wrote about above. Don’t forget, these emulators are for Linuxif you are using Windows or Macthen you will need to either find them for these systems, or assemble them yourself… Neither one nor the other is consoling…
don’t forget if you download the archive.
The password is 456123. I had to install it because there are executable files for Linux inside.
Important! The examples contain calls for the OS Linux! In order for the code in the examples to work with Windows or Mac you will have to find the information yourself and redo these examples.
You can also share this information with others. ))) If you find it.
In order to proceed to study the code that you will download from the link above, you need to know the assembler for all four of the listed architectures: x86/x86_64/Arm32/Arm64. As usual, I am posting information that is not entirely for beginners.
Install binutils for the required architectures, in this case these are: i686, x86_64, arm-eabihf (arm-eabi) and aarch64.
Read literature and sources if necessary.
Various information on assemblers.
aarch64 assembler.
Arm assembler.
Linux x86_64.
It will be useful to read the book”Rudolf Marek. Assembly language with examples.” chapter “Programming in Linux“.
I think there is a lot of information on the Internet, so look for it. Don’t forget the basic documentation provided by processor manufacturers and architects.
In this video, I go through setting up the necessary tools and go through the Hello World code for different architectures.
https://youtu.be/c9iC8GW-7mQ – I duplicate the link.
This is quite important information with system calls Linux for different architectures!
I created for myself Makefile and tweaked it a bit. Please do not judge too harshly, but I am not an expert in these matters, it probably could have been done better.
Makefile for helloGas.
CC64 = as
LC64 = gcc
CC32 = /usr/i686-linux-gnu/bin/as
LC32 = /usr/i686-linux-gnu/bin/ld
CCA64 = /usr/aarch64-linux-gnu/bin/as
LCA64 = /usr/aarch64-linux-gnu/bin/ld
CCA32 = /usr/arm-linux-gnueabihf/bin/as
LCA32 = /usr/arm-linux-gnueabihf/bin/ld
RA64 = ../qemu/qemu-aarch64
RA32 = ../qemu/qemu-arm
default: bX64 rX64
help:
bX64: HelloX64.asm
$(CC64) -g HelloX64.asm -o HelloX64.o
$(LC64) -s HelloX64.o -o HelloX64 -no-pie
rX64: HelloX64
clear
./HelloX64
bX32: HelloX32.asm
$(CC32) HelloX32.asm -o HelloX32.o
$(LC32) HelloX32.o -o HelloX32
rX32: HelloX32
clear
./HelloX32
bA64: HelloA64.asm
$(CCA64) -g HelloA64.asm -o HelloA64.o
$(LCA64) HelloA64.o -o HelloA64
rA64: HelloA64
clear
$(RA64) -L /usr/aarch64-linux-gnu/ -g 1234 ./HelloA64
bA32: HelloA32.asm
$(CCA32) -g HelloA32.asm -o HelloA32.o
$(LCA32) HelloA32.o -o HelloA32
rA32: HelloA32
clear
$(RA32) ./HelloA32
rgA32: HelloA32
clear
$(RA32) -L /usr/arm-linux-gnueabihf/ -g 1234 HelloA32
This Makefile was configured for x86_64 architecture. If you are developing on other architectures, some changes may be needed. And also some parameters in the file were made just for testing and you can remove them or add some of your own parameters.
Let’s turn our attention to the project assembly. These are: bX64, bX32, bA32 and bA64; Where b -build, X – x86, A – ARM. Same with the launch: rX64, rX32, rA32 and rA64; Where r – this is run. I hope everything else is clear.
As for the rest, many (many – that’s not all!) understand it better than me, and if you don’t understand this, then you’ll have to learn everything. I’m no help here at the moment, sorry. But looking ahead, you can do something look here, although this relates more to debugging, there is also important information there. Also see the documentation for Qemuin particular look here. This will probably help you understand everything (to be honest, I’ve already forgotten something, I’ll probably need to remember it too).
Yes, take a look at this topicthat’s where I started posting all the information and I might have missed something here.
Let’s take a quick look at the code for Hello World:
x86
// cpu x86_64
.global _start
.section .data
msg: .ascii "Hello World!\n"
len = . - msg # вычисляется длина строки
.section .text
_start:
mov $4, %eax # 4 - write
mov $1, %ebx # 1 - stdout
lea msg, %ecx # адрес сообщения
mov $len, %edx # длина сообщения - обязателен префикс '$' перед len
int $0x80
mov $1, %eax # 1 - exit
xor %ebx, %ebx # 0 - Return
int $0x80
x86_64
// cpu x86_64
.global _main
.section .data
msg: .ascii "Hello World!\n"
len = . - msg # вычисляется длина строки
.section .text
_main:
mov $len, %rdx # длина сообщения - обязателен префикс '$' перед len
mov $msg, %rsi # адрес сообщения
mov $1, %rdi # 1 - stdout
mov $1, %rax # 1 - write
syscall
xor %rdi, %rdi
mov $60, %rax
syscall
Arm32
// cpu ARM32
.global _start
.section .data
msg: .ascii "Hello World!\n"
len = . - msg
.section .text
_start:
mov r0, #1 // 1 - stdout
ldr r1, =msg // загружаем адрес строки
mov r2, #len // длина строки - интересная ситуация... требует префикс '#'
mov r7, #4 // write
swi 0
mov r0, #0 // код возврата
mov r7, #1 // exit
swi 0
Arm64
// cpu ARM64
.global _start
.section .data
msg: .ascii "Hello World!\n"
len = . - msg
.section .text
_start:
mov x0, #1 // 1 - stdout
ldr x1, =msg // адрес
mov x2, len // длина строки
mov x8, #64 // системный вызов write
svc 0 // программное прерывание, сгенерированное пользователем.
// (вызов супервизора...)
mov x0, #0 // код возврата
mov x8, #93 // указание на закрытие программы Exit - Terminate
svc 0
Looking through the code, you can see that it does not differ much for different architectures. This code differs in system calls and how the assembler works with comments. If for architectures Arm comments begin with “//“, then for architectures x86 they start with “#“… It is not clear what this is connected with… The assembler seems to be the same Gas. But these are the things you have to remember.
The code begins to differ more and more, the larger the application we develop becomes.
We must also not forget that registers for architectures Arm different. If for 32-bit these are registers r0–r15then for 64-bit these are registers x0-x31 (w0-w31 their lower part, which also diverges from the original registers).
The link to system calls was posted above and by looking at the code for different architectures you can see that they are different. Therefore, you should always pay attention to what architecture you are building the application for and use the necessary calls for this architecture.
If you wish, you can watch a video on assembler, the code of which I did not understand here.
In each video I did a code analysis. Each code is slightly documented and it will not be difficult for a person who is already familiar with assembler to understand it. At least I hope so.
Procedures read/write. (https://youtu.be/r7A0RfLG0l4 – duplicate).
debugging I posted the link above and will post it even lower, where we’ll look at debugging a little differently. But maybe it will be useful to someone. (https://youtu.be/eUiFfLebXM8 – duplicate).
Let’s touch on debugging a little.
There is a graphical debugger EDB. This is a fairly simple debugger and there are practically no problems figuring it out. But! This debugger works with architectures x86, x86_64 And Arm32… Arm64 it does not support… Also, to use this debugger you need to have a real machine on this architecture or at least an emulator with a working graphical shell…
Yes, I’ve created Arm emulators. But the graphical shell is Arm32 didn’t start, Arm64 works.
And, because of all of the above, I was looking for a way that would work everywhere. And I found it. Everything was done a long time ago and quite well planned. That’s why I settled on the debugger G.D.B.. Be sure to check it out if you also decide to use G.D.B. for debugging.
Another video where I made the StrToInt/StrToUInt functions. And also, at the 25th minute I analyze debugging using GDB.
I think this is where I should end the article. There is always a lot of information and… always little. Not enough, for the reason that people who know this information think that others also know about it. Or maybe they just don’t want to share or think it’s not necessary. But there is a need. I spent a lot of time collecting a drop in the ocean. And how many more drops have you not collected?
If you have any questions, please ask. Perhaps it is worth adding to the article and I missed something very important in it. But I hope I didn’t miss anything important.
I hope the information was useful to you! Best wishes!
Acknowledgement and Usage Notice
The editorial team at TechBurst Magazine acknowledges the invaluable contribution of the author of the original article that forms the foundation of our publication. We sincerely appreciate the author’s work. All images in this publication are sourced directly from the original article, where a reference to the author’s profile is provided as well. This publication respects the author’s rights and enhances the visibility of their original work. If there are any concerns or the author wishes to discuss this matter further, we welcome an open dialogue to address potential issues and find an amicable resolution. Feel free to contact us through the ‘Contact Us’ section; the link is available in the website footer.