Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Kod w Asemblerze odpowiadający fragmentowi kodu w C oraz instrukcja CALL

Zgredowy 19 Cze 2011 18:32 1193 8
  • #1 19 Cze 2011 18:32
    Zgredowy
    Poziom 2  

    Witam.

    Na wstępie chciałem zaznaczyć że jeżeli chodzi o Asemblera to jestem kompletnie zielony, a pech chciał że musze wykonać dwa zadania z nim związane, więc będe wdzięczny za każdą wskazówke i okazaną pomoc ;)

    Zad 1) Napisz kod w asemblerze odpowiadający fragmentowi kodu w C z wykorzystaniem TYLKO instrukcji MOV, SHL, SHR, SUB, JZ, JNZ, POP i PUSH (nie można używać ADD), do dyspozycji mamy rejestry AX(ah, al) - Akumulator, BX(bh,bl) - bazowy rejestr, CX(ch,cl) - licznikowy rejestr), DX(dh,dl) - rejestr danych. Szczerze mówiąc nie mam pojecia czym sie różnią te rejestry i co oznaczają zawartości nawiasów które są przy nich. Można wykorzystać również flagi.

    Kod w C jaki należy zamienić na kod w Asemblerze to:

    wyjscie= wejście * 12

    zmienna wejście oraz wyjście są 8-bitowe

    Zad 2. Podaj cykle wykonania instrukcji CALL etykieta.

    0 8
  • #2 19 Cze 2011 19:38
    Dżyszla
    Poziom 42  

    1. rejestry ax-dx to rejestry ogólnego przeznaczenia. Czyli w większości przypadków nie różnią się niczym. Ale mogą mieć też specyficzne zastosowania, jak AX do niektórych operacji arytmetyczno-logicznch, BX do wskazywania adresu (zapis: [BX]), CX używany do liczenia (podobnie, jak licznik w for).

    xH i xL to 8-bitowe części całego rejestru. czyli AX = AH|AL (zapis, jak widać). Matematycznie: AX = (AH << 8) + AL.

    Jako, że nie można używać ani dodawania ani mnożenia, to szczerze powiedziawszy nie mam za bardzo pomysłu, jak zrealizować działanie...

    EDYCJA: Może tak: wynik = wejście * (16 - 4) = wejscie * 16 - wejście * 4 = (wejście << 4) - (wejście << 2)

    :)

    0
  • #3 19 Cze 2011 19:55
    excray
    Poziom 39  

    Tutaj jest kod na dzielenie 2-óch liczb 8-bitowych dla AVR:

    Code:
                                     ;* "div8u" - 8/8 Bit Unsigned Division
    
                                        ;*
                                        ;* This subroutine divides the two register variables "dd8u" (dividend) and
                                        ;* "dv8u" (divisor). The result is placed in "dres8u" and the remainder in
                                        ;* "drem8u".
                                        ;*
                                        ;* Number of words   :14
                                        ;* Number of cycles   :97
                                        ;* Low registers used   :1 (drem8u)
                                        ;* High registers used  :3 (dres8u/dd8u,dv8u,dcnt8u)
                                        ;*
                                        ;***************************************************************************
                                       
                                        ;***** Subroutine Register Variables
                                       
                                        .def   drem8u   =r15      ;remainder
                                        .def   dres8u   =r16      ;result




                                        .def   dd8u   =r16      ;dividend
                                        .def   dv8u   =r17      ;divisor
                                        .def   dcnt8u   =r18      ;loop counter
                                       
                                        ;***** Code
                                       
                                        div8u:   sub   drem8u,drem8u   ;clear remainder and carry
                                           ldi   dcnt8u,9   ;init loop counter
                                        d8u_1:   rol   dd8u      ;shift left dividend
                                           dec   dcnt8u      ;decrement counter
                                           brne   d8u_2      ;if done
                                           ret         ;    return
                                        d8u_2:   rol   drem8u      ;shift dividend into remainder
                                           sub   drem8u,dv8u   ;remainder = remainder - divisor
                                           brcc   d8u_3      ;if result negative
                                           add   drem8u,dv8u   ;    restore remainder
                                           clc         ;    clear carry to be shifted into result
                                           rjmp   d8u_1      ;else
                                        d8u_3:   sec         ;    set carry to be shifted into result
                                           rjmp   d8u_1

    Podejrzewam że przerabiając ten kod - szczególnie okolice "ROL" uzyskasz efekt odwrotny czyli mnożenia.

    0
  • #4 19 Cze 2011 20:15
    Zgredowy
    Poziom 2  

    Z tego co wiem to używając SHL mnożymy, więc jako tako mnożenia można używać, tak mi się przynajmniej wydaje ;]

    Odnośnie podanego kodu, to niestety, jak już wspominałem z asemblerem za bardzo się nie lubimy i to co wkleiłeś jest dla mnie czarną magią ;/

    Mimo wszystko dziękuje za dotychczasowy odzew ;]

    Kolega rozpisał mi pare linijek kodu odnośnie pierwszego zadania

    MOV AX, wejscie
    MOV BX, AX
    SHL BX, 4
    MOV CX, AX
    SHL CX, 2
    SUB BX, CX
    MOV wyjscie, BX

    Niestety robił to na szybko i nie za bardzo wyjaśnił mi co dokładnie z tego kodu wynika, dzięki potędze internetu troche o tym poczytałem i mniej wiecej rozumiem ten kod, ale nie do końca wiem czy jest on poprawny do tego zadania, więc prosze o jego weryfikacje ;)

    0
  • #5 19 Cze 2011 20:28
    excray
    Poziom 39  

    SHL to mnożenie ale *2 czyli 3 x SHL x = x*2*2*2 czyli

    MOV AX, wejscie
    MOV BX, AX - AX=BX = wejście
    SHL BX, 4 - BX = wejście *16 (2*2*2*2)
    MOV CX, AX - CX=AX=wejście
    SHL CX, 2 - CX=wejście *4
    SUB BX, CX - BX-CX czyli (wejście *16)-(wejście*4)=wejście *12=BX
    MOV wyjscie, BX -wyjście =BX

    kod jest poprawny

    0
  • #6 19 Cze 2011 22:36
    Akane
    Poziom 27  

    excray napisał:
    MOV AX, wejscie
    MOV wyjscie, BX

    Te dwa rozkazy nie są poprawne gdy wejscie i wyjscie jest ośmiobitowe. Pierwsze mov powinno być zamienione na movzx (lub zamienić AX na AL), a w drugim zamiast BX, powinno być BL.

    Kod: asm
    Zaloguj się, aby zobaczyć kod


    Ewentualnie na pełnych rejestrach:
    Kod: asm
    Zaloguj się, aby zobaczyć kod

    0
  • #7 21 Cze 2011 14:52
    Zgredowy
    Poziom 2  

    Dziękuje bardzo :D

    A mógłbyś mi jeszcze wyjaśnić dlaczego powinno być AL zamiast AX i BL zamiast BX?

    0
  • #8 21 Cze 2011 15:02
    loganek2
    Poziom 16  

    AX jest rejestrem 16-bitowym. Wejście jest 8-bitowe, tak więc korzystasz z 8 bitów rejestru. 8 najmłodszych bitów rejestru AX to AL(L - low). Tak samo dla BX

    0
  • #9 21 Cze 2011 15:21
    Zgredowy
    Poziom 2  

    Myśle że to co napisaliście powinno wystarczyć. Wielkie dzięki ;)

    0