Showing posts with label Ассемблэр. Show all posts
Showing posts with label Ассемблэр. Show all posts

2010-03-22

Berkeley RISC I

RISC төрлийн архитектуртай Berkeley RISC I ассемблэр дээр код бичиж үзлээ.


N EQU 10
DIZI EQU $500

 ORG $500
 DCINT 7
 DCINT -98
 DCINT 5
 DCINT 678
 DCINT -832
 DCINT 4567
 DCINT -789
 DCINT 409
 DCINT -372
 DCINT 65


 ORG $600
START:
 ADD R0,N,R17  
 XOR R16,R16,R16  
 SLL R17,2,R17  
back: 
 LDL (R16)DIZI,R2  
 CALL deltaD(R0),R3 
 NOP
 STL (R16)DIZI,R2  
 ADD R16,4,R16  
 NOP
 SUB R16,R17,R18  
 NOP
 JMP BMI,back(R0) 
 NOP
 NOP

 ORG $700
deltaD: 
 SLL R2,1,R21  
 JMP BMI,neg(R0)  
 NOP
 NOP
 
 SLL R2,2,R2  
 RET (R0)R3
 NOP

neg: 
 SUB R0,R2,R2  
 NOP 
 RET (R0)R3
 NOP


2009-12-25

Ассемблэр дээр програм бичих

Өчигдөр CodeWarrior татаж авлаа, үнэхээр лаг юмаа хэхэ. Ингээд доор сарыг аваад тухайн сар хэдэн хоногтойг A аккумляторт буцаадаг програс бичлээ. LCD цаг хийсэн лабораторт хэрэг болсон юм л даа. Илүү хурдан ажиллах кодны санаа байвал хуваалцаарай хүмүүсээ.
MY_EXTENDED_RAM: SECTION
YEAR        DS.w 1
MONTH       DS.b 1
DAY         DS.b 1

MyCode:     SECTION
main:
_Startup:
Entry: 
            LDD    #2006
            STD    YEAR
            LDAA   #4
            STAA   MONTH
            LDAA    #5
            STAA   DAY
            JSR   DAYBYMONTH
            SWI

DAYBYMONTH:             ; returns # of days in ACC A
            LDAB   MONTH    
            CMPB   #2      
            BEQ   TSTLEAP  
                       
            CMPB   #8       
            BGE   AUTUMN   
            LDAA   MONTH     
            ASRA 
            BCC     D30
            LDAA    #31      
            RTS
AUTUMN:     
            LDAA   MONTH     
            ASRA 
            BCS     D30
            LDAA    #31
            RTS
D30:        
            LDAA    #30
            RTS
TSTLEAP:
            LDD   YEAR
            LDX   #4
            IDIV
            TBNE   D,NOTLEAP
            LDAA   #29
            RTS
NOTLEAP:
            LDAA   #28
            RTS

2009-11-15

Моторолла 6800

Моторолла 6800 бол нилээн дээхний 8 бит дээр ажилладаг бичил схем билээ. Өмнөх бичлэг дээр Intel x86 дээр бичсэн Фибоначийн дараалал олдог бодлогыг MC6800 дээр бичье.
  org $0000
  clra
  clrb  
  ldaa #6  ; find F6
  staa $001E  ; n=6
  ldaa #1  ; A=F0
  ldab #1  ; B=F1
start: staa $001F  ; Fn=A
  aba   ; A=A+B  
  dec $001E  ; n=n-1  
  tst $001E  ; test if n=0
  bne notyet ; if not branch to notyet   
  swi   ; software interrupt  
notyet: ldab $001F  ; b=Fn
  jmp start  ; jump to start


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