2009-11-11

Ассемблэр дээр код бичих

Ассемблийн хэл дээр бичигдсэн програм нь машины хэлрүү хялбархан хөрвүүлэгдэнэ. Энд NASM ашиглан жишээнүүд авч үзье. NASM нь Intel x86 хэл дээр ажиллана. Доорх програмыг авч үзье:
segment .data                   ; used for assigned variables
  msg  db   "Hello, world!",10
  len  equ  $ - msg             ; macro to calculate length of msg
                                ; equ for constant, ($-msg) means substract
                                ; msg's head address location from current address location

segment .text

global _start

_start:                         ; starting point

  mov  eax,4                    ; print system call
  mov  ebx,1                    ; standard output
  mov  ecx,msg                  ; the message to print
  mov  edx,len                  ; the length
  int  80h                      ; software interrupt

  mov  eax,1                    ; exit system call
  mov  ebx,0                    ; successful
  int  80h                      ; software interrupt

гэж бичээд foo.asm нэр өгч хадгалья. Дээрх програмын обьект файлыг Линүксд зориулж үүсгэхдээ:
nasm -f elf foo.asm -o foo.o
Одоо доорх коммандаар машины хэл дээрх кодыг нь харья:
nasm -f elf foo.asm -l foo.lis
Ингэхэд foo.lis файл үүссэн байна. Агуулгыг нь харвал:
1                                  segment .data
2 00000000 48656C6C6F2C20776F-     msg  db   "Hello, world!",10
3 00000009 726C64210A         
4                                  len  equ  $ - msg
5                                  
6                                  segment .text
7                                  global _start
8                                  
9                                  _start:
10 00000000 B804000000                  mov  eax,4
11 00000005 BB01000000                  mov  ebx,1
12 0000000A B9[00000000]                mov  ecx,msg
13 0000000F BA0E000000                  mov  edx,len
14 00000014 CD80                        int  80h
15                                  
16 00000016 B801000000                  mov  eax,1
17 0000001B BB00000000                  mov  ebx,0
18 00000020 CD80                        int  80h
эндээс компьютэрийн RAM санамж дээр бичигдэж ажиллах машины код харагдаж байна. Хэдийгээр эхний хаяг 0x00000000 гэж харагдаж байгаа ч санамжинд хуулагдах үед үйлдлийн систем хоосон буй өөр хаягаа оноож өгнө. Дээрх машины коп нь програмаас гараад software interrupt хийж байгаа учир линкэр ашиглан уншигддаг програм болгож болно:
ld foo.o -o foo -e _start
Тэгээд шууд ./foo гээд ажиллуулж болно. Одоо өөр нэг жишээ авч үзье. Доорх жишээнд C хэл дээр бичигдсэн програмаас ассемблэрийн хэл дээр бичигдсэн рутинийг ажиллуулах болно. bar.c
#include 

int star();
int fibo(int k);

int main() {
 int k,i;
 k = star();
 printf("Number is: %d\n", k);
 k = fibo(5);
 printf("5-th Fibonacci number is: %d\n", k);
 for(i=0;i<=8;i++) {
  printf("%d ", fibo(i));
 }
 printf("\n");
 return 0;
}

bar.asm

global star
global fibo

segment .bss
 sum resb 1

segment .text

star: mov ecx,8
 mov edx,9
 add ecx,edx
 mov [sum],ecx
 mov eax,[sum] 
 ret
fibo: push ebp
 mov ebp,esp
 mov eax,1
 mov ebx,1
 mov edx,[ebp+8]
 cmp edx,1
 jle fstop
 dec edx
fstep: mov ecx,eax
 add eax,ebx
 dec edx
 mov ebx,ecx
 cmp edx,0
 jne fstep 
fstop: pop ebp 
 ret
Ажиллуулахдаа:

1 - Ассемблэр кодноос обьект файл үүсгэнэ:

    nasm -f elf bar.asm -o barasm.o
2 - C кодноос обьект файл үүсгэнэ:
    gcc -c bar.c -o barc.o
3 - Обьект файлуудыг холбоно:
    gcc barasm.o barc.o -o bar
4 - Програмыг ажиллуулна:
    ./bar

No comments:

Post a Comment