Friday, December 18, 2015

Assembly Language

Writing assembler code is very difficult, it's difficult because you have to write lowest level programming language, you have to write code specific to architecture of machine, 32bit or 64bit machines.

Take a look at following assembly code written for x86_64 machine. This code loops until start reaches to value in max and prints out each value.

.globl    _start    /* must declare for program to know where to start program, it's just says which is main function. */

.set     start, 0     /* starting value for the loop index */
.set     max, 10    /* loop exits when the index hits this number (loop condition is i<max) */
_start:
mov     $start,%r15    /* loop index */
loop:
mov     %r15,%r14     /* copy to r14 for ascii conversion */
mov     $'0',%r13        /* loding value of start into r13 register */
add      %r13,%r14     /* adding r13 and r14 values and result is store into r14 register */
movq   $digit,%rsi       /* message location, rsi is register source index */
movb   %r14b,(%rsi)  /* write byte to start of message */
movq   $len,%rdx       /* message length, rdx is register d extended */
movq   $msg,%rsi      /* message location, rsi is register source index */
movq   $1,%rdi          /* file descriptor stdout, rdi is register destination index */
movq   $1,%rax         /* syscall, sys_write, rax is register a extended */
syscall

inc       %r15              /* increment register 15 */
cmp     $max,%r15    /* see if we're done */
jne       loop               /* loop if we are not */

mov     $0,%rdi         /* exit status */
mov     $60,%rax      /* syscall sys_exit */
syscall 

.data
msg:    .ascii    "Loop: #\n"   /* message text - # is number of index */
digit = . - 2                           /* memory address for digit */
len = . - msg                         /* length of message */

The code belongs to Chris Tyler and some of the comments belongs to him as well, it's quite difficult to understand some of the steps. This code is able to handle only single digit value for being printed. All the registers that were used in code above are for only x86_64 machine, for Aarch64 there are different set of registers. Take a look at following table for some basic difference between x86_64 and Aarch64 machine.


X86_64 Aarch64
R8 to r15 are general registers r0 to r30 are general registers
rax, rbx, rcx, rdx, rbp, rsp, rsi, rdi are specialied regisers -
64-bit registers using the 'r' prefix: rax, r15

32-bit registers using the 'e' prefix (original registers: e_x) or 'd' suffix (added registers: r__d): eax, r15d

16-bit registers using no prefix (original registers: _x) or a 'w' suffix (added registers: r__w): ax, r15w

8-bit registers using 'h' ("high byte" of 16 bits) suffix (original registers - bits 8-15: _h): ah, bh

8-bit registers using 'l' ("low byte" of 16 bits) suffix (original registers - bits 0-7: _l) or 'b' suffix (added registers: r__b): al, bl, r15b
x0 through x30 - for 64-bit-wide access registers w0 through w30 - for 32-bit-wide access registers
Openrations like add, divide, multiply takes two parameters and operation result is stored in second parameter. Openrations like add, divide, multiply takes three parametrs and result is stored in first parameter and other two are for operation values.
Many differences.. Many differences..

One of the good thing about writing assembly code is when you compiler it and analyze executable file using objdump command you will not see any code other than what you have written but when you write C/C++ code and analyze it' executable there is a lot of other code that you didn't write, that code is coming from your includes but since you don't need to include anything in assembly code so what you write is what you get. This assembly program is written in .s type extension and you just run:
ls -o name.o file.s
ld -o executable-name name.o

You can also write/add assembly code in your C/C++ program using asm function, ex: asm("add $1, %0"). And to compile this you can just using gcc or g++ compiler.

No comments:

Post a Comment