Hirdetés

Új hozzászólás Aktív témák

  • Sziasztok!

    Olyan feladatom lenne, hogy egyfajta cpu stress-tesztet kellene csinálnom assemlby nyelven visual studioban (c++/c#). Nincs valami ötletetek, hogy mi az a folyamat ami leginkább leterheli a processzort? esetleg egy pléda is jól jönne nagyvonalakban. (A progi lényege hogy a procit 100%-on járassa míg lefut a program)

    Köszönöm!

  • jattila48
    aktív tag

    Sziasztok!

    Visual Studio 2012-ből szeretnék C++ forráskódból assembly listát generálni (/Fa kapcsolóval), majd tovább fordítani masm-mal. Az a gond, hogy a generált assembly lista a masm (ml) szerint szintaktikusan hibás. Mit lehet tenni? Az nem opció, hogy javítsam ki kézzel. Esetleg van-e más fordító, ami tovább fordítható masm formátumú assembly listát generál?

  • Jester01
    veterán

    Helló, van valakinek valami ötlete, hogyan lehetne XMM regiszterből a 0. és 4. szavat összeadni? Esetleg valahogy azt megoldani, hogy 128 bites regiszterből 32 bitesbe másolni?

    Persze. De neked is lenne ha elővennéd az utasításkészlet leírását :P
    Lásd PSHUFD, PEXTRD

  • Helló, van valakinek valami ötlete, hogyan lehetne XMM regiszterből a 0. és 4. szavat összeadni? Esetleg valahogy azt megoldani, hogy 128 bites regiszterből 32 bitesbe másolni?

  • VIC20
    őstag

    Sziasztok!

    Tudna valaki segíteni? Keresem Pethő Ádám: Variációk Assamblyre című könyvének a lemezmellékletét (pontosabbal a tartalmát). Sajnos a külső floppymeghajtóm nem olvassa be a lemezt, vagy azért, mert 20 éves a floppy, vagy azért, mert DD-s.

    Kérem, akinek megvan, az töltse fel valamilyen fájlmegosztóra vagy küldje el e-mail-ben. Előre is köszönöm szépen!

  • Ha linuxon vagy akkor akkor a megfelelő blokk eszközre írod. Duplán ellenőrizd, hogy véletlenül ne rossz helyre, például a rendszerlemezedre, írd. Pl.: dd if=boot.bin of=/dev/sdX

    windows
    Elfelejtettem írni, bocs. :B

  • Jester01
    veterán

    Még egy kérdésem lenne, higy tudom ezt mondjuk egy pendrive-ra kiírni és élesben kipróbálni?

    Ha linuxon vagy akkor akkor a megfelelő blokk eszközre írod. Duplán ellenőrizd, hogy véletlenül ne rossz helyre, például a rendszerlemezedre, írd. Pl.: dd if=boot.bin of=/dev/sdX

  • Még egy kérdésem lenne, higy tudom ezt mondjuk egy pendrive-ra kiírni és élesben kipróbálni?

  • DOS hívást értelemszerűen nem használhat boot sectorból, hiszen nincs DOS. :U
    String kiíráshoz ciklust lehet használni avagy az int 10h/13h funkciót.

    org 0x7c00
    mov si, MSG
    call print
    jmp $
    print:
    mov ah, 0x0e
    lodsb
    test al, al
    jz done
    int 0x10
    jmp print
    done:
    ret

    MSG: db "Alma",0

    times 510-($-$$) db 0
    dw 0xaa55

    :R

  • zka67
    őstag

    DOS hívást értelemszerűen nem használhat boot sectorból, hiszen nincs DOS. :U
    String kiíráshoz ciklust lehet használni avagy az int 10h/13h funkciót.

    org 0x7c00
    mov si, MSG
    call print
    jmp $
    print:
    mov ah, 0x0e
    lodsb
    test al, al
    jz done
    int 0x10
    jmp print
    done:
    ret

    MSG: db "Alma",0

    times 510-($-$$) db 0
    dw 0xaa55

    Ja, igazad van, bocs.

  • Jester01
    veterán

    Szia, először is:
    mov al,"a"

    Ha elolvasod a BIOS funkció paraméterét, te is láthatod, hogy az csak egy karaktert ír ki a TTY-ra, mégpedig azt, ami az AL regiszterben van. Ha jól emlékszem, akkor a BH és BL regisztereket is be kell állítani, mielőtt meghívod a 10h megszakítást. (BH=page, BL=color).

    Használhatod helyette a DOS hívásokat, INT 21h

    Function 2h: Display Output. Outputs the character in DL to the standard output device.
    Input: AL = 02h, DL = character
    Output: none

    Szöveg kiírásához pedig ezt:

    Function 09h: Print String. Outputs the characters in the print string to the standard output device.
    Input: AH=09h, DS:DX = pointer to the character string ending with '$'
    output: none

    org 0x7c00
    mov dl,"a"
    call print
    jmp $
    print:
    mov ah,2
    int 21h
    ret


    org 0x7c00
    mov dx,MSG
    call print
    jmp $
    print:
    push ds
    mov ax,cs
    mov ds,ax
    mov ah,9
    int 21h
    pop ds
    ret
    MSG:
    db "Alma$"

    DOS hívást értelemszerűen nem használhat boot sectorból, hiszen nincs DOS. :U
    String kiíráshoz ciklust lehet használni avagy az int 10h/13h funkciót.

    org 0x7c00
    mov si, MSG
    call print
    jmp $
    print:
    mov ah, 0x0e
    lodsb
    test al, al
    jz done
    int 0x10
    jmp print
    done:
    ret

    MSG: db "Alma",0

    times 510-($-$$) db 0
    dw 0xaa55

  • Szia, először is:
    mov al,"a"

    Ha elolvasod a BIOS funkció paraméterét, te is láthatod, hogy az csak egy karaktert ír ki a TTY-ra, mégpedig azt, ami az AL regiszterben van. Ha jól emlékszem, akkor a BH és BL regisztereket is be kell állítani, mielőtt meghívod a 10h megszakítást. (BH=page, BL=color).

    Használhatod helyette a DOS hívásokat, INT 21h

    Function 2h: Display Output. Outputs the character in DL to the standard output device.
    Input: AL = 02h, DL = character
    Output: none

    Szöveg kiírásához pedig ezt:

    Function 09h: Print String. Outputs the characters in the print string to the standard output device.
    Input: AH=09h, DS:DX = pointer to the character string ending with '$'
    output: none

    org 0x7c00
    mov dl,"a"
    call print
    jmp $
    print:
    mov ah,2
    int 21h
    ret


    org 0x7c00
    mov dx,MSG
    call print
    jmp $
    print:
    push ds
    mov ax,cs
    mov ds,ax
    mov ah,9
    int 21h
    pop ds
    ret
    MSG:
    db "Alma$"

    Hát, nem akaródzik neki működni... :F

  • zka67
    őstag

    Sziasztok, gondoltam kicsit bepillantok az operációs rendszer fejlesztésbe (semmi komoly dolgot nem akarok, csak, hogy legyen némi elképzelésem a dolgokról)

    A könyv alapján , amit olvasok, ezt raktam össze:

    org 0x7c00
    mov ax, "a"
    call print
    jmp $
    print:
    mov ah, 0x0e
    int 0x10
    ret

    times 510-($-$$) db 0
    dw 0xaa55

    Ezt Bochs-al el is indítom és ki is írja az a betűt, viszont ha átírom így:

    org 0x7c00
    mov ax, MSG
    call print
    jmp $
    print:
    mov ah, 0x0e
    int 0x10
    ret
    MSG:
    db "Alma",0

    times 510-($-$$) db 0
    dw 0xaa55

    Akkor nem ír ki semmit. Ez miért van?

    Szia, először is:
    mov al,"a"

    Ha elolvasod a BIOS funkció paraméterét, te is láthatod, hogy az csak egy karaktert ír ki a TTY-ra, mégpedig azt, ami az AL regiszterben van. Ha jól emlékszem, akkor a BH és BL regisztereket is be kell állítani, mielőtt meghívod a 10h megszakítást. (BH=page, BL=color).

    Használhatod helyette a DOS hívásokat, INT 21h

    Function 2h: Display Output. Outputs the character in DL to the standard output device.
    Input: AL = 02h, DL = character
    Output: none

    Szöveg kiírásához pedig ezt:

    Function 09h: Print String. Outputs the characters in the print string to the standard output device.
    Input: AH=09h, DS:DX = pointer to the character string ending with '$'
    output: none

    org 0x7c00
    mov dl,"a"
    call print
    jmp $
    print:
    mov ah,2
    int 21h
    ret


    org 0x7c00
    mov dx,MSG
    call print
    jmp $
    print:
    push ds
    mov ax,cs
    mov ds,ax
    mov ah,9
    int 21h
    pop ds
    ret
    MSG:
    db "Alma$"

  • Sziasztok, gondoltam kicsit bepillantok az operációs rendszer fejlesztésbe (semmi komoly dolgot nem akarok, csak, hogy legyen némi elképzelésem a dolgokról)

    A könyv alapján , amit olvasok, ezt raktam össze:

    org 0x7c00
    mov ax, "a"
    call print
    jmp $
    print:
    mov ah, 0x0e
    int 0x10
    ret

    times 510-($-$$) db 0
    dw 0xaa55

    Ezt Bochs-al el is indítom és ki is írja az a betűt, viszont ha átírom így:

    org 0x7c00
    mov ax, MSG
    call print
    jmp $
    print:
    mov ah, 0x0e
    int 0x10
    ret
    MSG:
    db "Alma",0

    times 510-($-$$) db 0
    dw 0xaa55

    Akkor nem ír ki semmit. Ez miért van?

  • vanek
    tag

    Sikerült a main közepébe beszúrkálni egyebeket. A vege és a main endp jó lenne ha kicsit korábban lenne, mondjuk célszerűen az olvas előtt. Az is meglep, hogy a fordító nem sírt miatta. Ezen felül a stosb az es szegmenst használná amit te nem állítottál be. Vagy tedd ezt meg, vagy használj ds override-ot. A main elején van 2 push amivel nem tudom mit szerettél volna, de az tuti, hogy azok a veremben maradnak és így a retf rossz helyre fog visszatérni. Abban sem vagyok biztos (környezettől függő) hogy a main-t egyáltalán lezárhatod-e retf utasítással vagy mindenképp DOS hívás kell (vagy near ret).

    Egyébként ha nem feltétlen muszáj akkor ne tanulj már 16 bites DOS dolgokat mert igencsak elavult. Viszont mindenképp tanulj meg egy debuggert kezelni, mert azzal fogod tudni megnézni mit is csinál a programod és hol csinál mást mint amit szeretnél.

    Köszönök minden segítséget, volt rá időm és összedobtam egy kódot..

    Mivel sajnos még nem nagyon tiszta a regiszterek használata, így szeretném azt kérni, hogy lehetne ellenőrizni..

    ;Kosntans

    LF equ 10
    CR equ 13
    Space equ 32





    KOD SEGMENT PARA PUBLIC 'CODE'


    ASSUME CS:KOD, DS:DATA, SS:VEREM, ES:DATA


    ANAGRAMMA PROC FAR

    mov ax, DATA
    mov ds, ax
    mov es, ax

    ; főprogram

    mov ax, offset szoveg
    mov si, ax
    call kiir
    mov si, offset szo1
    call olvasbill
    mov si, offset szo2
    call olvasbill
    mov bx, offset szo1
    call rendez
    mov bx, offset szo2
    call rendez
    call hasonlit
    ; főprogram vége

    mov ah, 4ch
    mov al,00h
    int 21h





    ;--------------------------------------------------------

    olvasbill proc
    push si ;si mentése
    olv:
    mov ah, 1h ;bios eljárás sorszáma
    int 21h ;bios interrupt
    cmp al, SPACE ;Space kódja
    je olvasvege
    cmp al, CR
    je olvasvege
    mov [si], al ;betű tárolása a memóriában
    inc si ;a következő betű egyel magasabb mem. címre kerüljön
    jmp olv ;vissza az olvasás elejére

    olvasvege:
    mov byte ptr [si], SPACE ;a string veget space-val lezárjuk
    int 10h
    pop si
    ret
    olvasbill endp


    ;--------------------------------------------------------

    min proc

    mov dl, [bx] ;dl-ben az elso betű
    mov si, bx ;si mutasson az elejére
    c1: mov al, [si] ;akt betú betöltése
    cmp al, SPACE ;space, vagyis szó vége
    je vege1 ;ha igen: vége
    cmp al, dl ;akt. betű és az eddigi legkisebb
    jae c2 ;ha az akt. nagyobb ugorjunk
    mov dl, al ;jegyezzük meg mert kisebb
    xchg al, [bx] ;csere
    mov [si], al ;csere
    c2: inc si ;köv betű
    jmp c1 ;
    vege1: ret ;visszatérés
    min endp


    rendez proc
    c3: mov al, [bx] ;akt betű betölt
    cmp al, SPACE ;szó vége?
    je vege2 ;ha igen: vége
    call min ;tegyük az elejére a legkisebbet
    inc bx ;köv betű
    jmp c3
    vege2: ret ;eljárás vége
    rendez endp

    ;-----------------------------------------------------------

    hasonlit proc
    mov si, offset szo1
    mov di, offset szo2
    ;PUSH DS
    ;POP ES
    cld
    mov cx, 40 ;string hossza
    repe cmpsb ;összehasonlít
    je igen
    jne nem
    nem:

    mov si, offset szovegnemjo ; Nem Anagramma
    call kiir
    ret ; Visszatérés az op. rendszerhez
    igen:

    mov si, offset szovegjo ; Anagramma
    call kiir
    ret ; Visszatérés az op. rendszerhez

    hasonlit endp

    ;--------------------------------------------------------

    betukiir proc ;al ben a kiirandó betű
    mov ah, 14 ;BIOS rutin paramétere
    int 10h ;10h megszakítás hívása
    ret ;visszatérés
    betukiir endp

    ;--------------------------------------------------------

    kiir proc
    push si
    kov: mov al, [si] ;következő betű
    cmp al, 0 ;0 jelzi a str végét
    je strvege ;ha elértünk a végére ugrunk
    call betukiir ;egy betű kiirása
    inc si ;mutató a következő betűre
    jmp kov ;ugrás
    strvege:
    pop si
    ret ;eljárás vége
    kiir endp


    KOD ENDS

    ;========================================================

    DATA SEGMENT PARA PUBLIC 'DATA'


    szoveg db "Kerem a ket szot szokozzel elvalasztva: ",0
    szovegjo db "A ket szo anagramma!",0
    szovegnemjo db " A ket szo nem anagramma!",0

    szo1 db 40 dup (0)
    szo2 db 40 dup (0)






    DATA ENDS

    ;========================================================

    VEREM SEGMENT PARA STACK
    dw 1024 dup (0)
    VEREM ENDS




    END ANAGRAMMA

    igazából a hibákra vagyok kíváncsi.. működni jól működik, szóval azzal nincs gond.

    Előre is köszönöm!

  • Jester01
    veterán

    Üdv!

    Azzal kezdenék, hogy totális kezdő vagyok...de nagyon próbálkozom! :D

    két szót szeretnék beolvasni egy sorból és a végüket pedig szóköz jelzi..

    kod segment para public 'code'
    assume cs:kod, ds:adat, ss:verem, es:nothing

    main proc far
    push ds
    xor ax, ax
    push ax
    mov ax, adat
    mov ds, ax

    ;főprogram

    mov dx, offset text1
    mov ah, 09h
    int 21h

    mov di, offset szo1
    call beolvas

    mov di, offset szo2
    call beolvas

    ;=====karakter beolvasása======

    olvas proc

    xor ah, ah
    int 16h
    ret

    olvas endp

    ;=====beolvasás================

    beolvas proc

    be:
    call olvas
    cmp al, 10
    je over
    cmp al, 13
    je over
    cmp al, 32
    je over
    stosb
    jmp be

    over: ret


    beolvas endp


    vege: retf

    main endp

    kod ends
    ;-------------------------------

    adat segment para public 'adat'

    text1 db 'kerem a ket szot szokozzel elvalasztva : $'
    szo1 db 40 dup (0)
    szo2 db 40 dup (0)

    adat ends

    ;-------------------------------

    verem segment para stack


    db 1024 dup (0)


    verem ends


    end main

    Az eredmény az, hogy kiírja, TEXT1 -et, majd kifagy..vagy ha nem, akkor akármit nyomok megint kiírja, TEXT1-et..:\

    előre is köszi! :)

    Sikerült a main közepébe beszúrkálni egyebeket. A vege és a main endp jó lenne ha kicsit korábban lenne, mondjuk célszerűen az olvas előtt. Az is meglep, hogy a fordító nem sírt miatta. Ezen felül a stosb az es szegmenst használná amit te nem állítottál be. Vagy tedd ezt meg, vagy használj ds override-ot. A main elején van 2 push amivel nem tudom mit szerettél volna, de az tuti, hogy azok a veremben maradnak és így a retf rossz helyre fog visszatérni. Abban sem vagyok biztos (környezettől függő) hogy a main-t egyáltalán lezárhatod-e retf utasítással vagy mindenképp DOS hívás kell (vagy near ret).

    Egyébként ha nem feltétlen muszáj akkor ne tanulj már 16 bites DOS dolgokat mert igencsak elavult. Viszont mindenképp tanulj meg egy debuggert kezelni, mert azzal fogod tudni megnézni mit is csinál a programod és hol csinál mást mint amit szeretnél.

  • vanek
    tag

    Üdv!

    Azzal kezdenék, hogy totális kezdő vagyok...de nagyon próbálkozom! :D

    két szót szeretnék beolvasni egy sorból és a végüket pedig szóköz jelzi..

    kod segment para public 'code'
    assume cs:kod, ds:adat, ss:verem, es:nothing

    main proc far
    push ds
    xor ax, ax
    push ax
    mov ax, adat
    mov ds, ax

    ;főprogram

    mov dx, offset text1
    mov ah, 09h
    int 21h

    mov di, offset szo1
    call beolvas

    mov di, offset szo2
    call beolvas

    ;=====karakter beolvasása======

    olvas proc

    xor ah, ah
    int 16h
    ret

    olvas endp

    ;=====beolvasás================

    beolvas proc

    be:
    call olvas
    cmp al, 10
    je over
    cmp al, 13
    je over
    cmp al, 32
    je over
    stosb
    jmp be

    over: ret


    beolvas endp


    vege: retf

    main endp

    kod ends
    ;-------------------------------

    adat segment para public 'adat'

    text1 db 'kerem a ket szot szokozzel elvalasztva : $'
    szo1 db 40 dup (0)
    szo2 db 40 dup (0)

    adat ends

    ;-------------------------------

    verem segment para stack


    db 1024 dup (0)


    verem ends


    end main

    Az eredmény az, hogy kiírja, TEXT1 -et, majd kifagy..vagy ha nem, akkor akármit nyomok megint kiírja, TEXT1-et..:\

    előre is köszi! :)

  • zka67
    őstag

    Sziasztok!

    Az lenne a kérdésem, hogy assemblyben hogyan tudom kideríteni, hogy egy szám elfér-e egy dupla szóban?
    A válaszokat előre is köszönöm!

    Megszorzod 10-zel az eredményt, ha túlcsordulás van (CY vagy OV attól függően, hogy előjel nélküli vagy előjeles számról beszélünk), akkor nem fért bele. A következő lépésben hozzáadod az új karakter értékét, és ha túlcsordulás van, nem fért bele. Ezt a két lépést ismétled addig, amíg a számod összes karakterét fel nem dolgoztad. Az eredményt az elején természetesen nullázod, és ha előjeles számról van szó és negatív, azt is pozitív számként kezeled és csak a végén negálod meg.

  • Jester01
    veterán

    Sziasztok!

    Az lenne a kérdésem, hogy assemblyben hogyan tudom kideríteni, hogy egy szám elfér-e egy dupla szóban?
    A válaszokat előre is köszönöm!

    Kicsit homályos ez a kérdés. Mindenesetre egy szokásos dword-be előjel nélkül 2^32-1 a legnagyobb szám ami belefér.

  • szucs.miki
    csendes tag

    Sziasztok!

    Az lenne a kérdésem, hogy assemblyben hogyan tudom kideríteni, hogy egy szám elfér-e egy dupla szóban?
    A válaszokat előre is köszönöm!

  • birno
    addikt

    Bocsánatot kérek!

    A feladat:
    "Az 1...1000 közötti egész számokat római számként tárolja egy ASCII
    sztring. Írjon programot, amely előállítja és kiírja a számot a tízes
    számrendszerben. "
    Javasolt a számokat elválasztani.
    Tagolást hogy gondolom? Pl. a Sztring ami tárolja a római számokat hogy
    néz ki:
    "MCCCXXVIII.DCXLII.MMXIII.IV.XXVI"
    ezt átfordítva decimálisra:
    1328 642 2013 4 26

    Valaki ebben tudna segíteni? Érthetően elmondani, kommentezni, mi miért van? Mert nekem elég gyengén megy az assembly.

    Amit beírtál string az gondolom csak találgatás, mivel nem 1 és 1000 közti számokat tartalmaz.
    Nagyon nem mindegy, hogy ténylegesen hogy néz ki a string, ezt gondolom csak megadták.
    Plusz ha jól értem akkor bele se kezdtél?
    Semmid nincs még?
    Csak mert megírni nem nagyon fogja senki helyetted.

  • Brownn
    tag

    Bocsánatot kérek!

    A feladat:
    "Az 1...1000 közötti egész számokat római számként tárolja egy ASCII
    sztring. Írjon programot, amely előállítja és kiírja a számot a tízes
    számrendszerben. "
    Javasolt a számokat elválasztani.
    Tagolást hogy gondolom? Pl. a Sztring ami tárolja a római számokat hogy
    néz ki:
    "MCCCXXVIII.DCXLII.MMXIII.IV.XXVI"
    ezt átfordítva decimálisra:
    1328 642 2013 4 26

    Valaki ebben tudna segíteni? Érthetően elmondani, kommentezni, mi miért van? Mert nekem elég gyengén megy az assembly.

  • zka67
    őstag

    Valaki aki kicsit is ért az assemblyben való programozáshoz, az kérem írna egy pm-et?

    Azért van ez a topik, hogy bátran feltehesd itt a kérdésedet.

  • Brownn
    tag

    Valaki aki kicsit is ért az assemblyben való programozáshoz, az kérem írna egy pm-et?

  • birno
    addikt

    Mert a példaprogramod 16 bites dos kód, a vs alá meg 32 bites windows kód kell. Szerintem.

    Az lehet, de akkor magyarul ilyen kóddal nem is használható a VS?
    Csak mert suliba meg ilyeneket hoznak példának, bár nem VS-be mutatják be, csak abba valszeg egyszerűbb lenne a debug.
    Én ezen leírás alapján állítottam be dosbox-ba, azzal az masm-el ami a linken van, azzal megy is, csak fogalmam nincs hogy fordítsam le úgy, hogy legalább Turbo debugger megegye, mert mindig "Program has invalid symbol table" üzenetet dob.

  • Jester01
    veterán

    Sziasztok,

    Visual Studio 2010-et akarnám összelőni, hogy lehessen vele assembly-t fordítani, ezen s ehhez hasonló tutorialok alapján(kb. mindbe ugyanaz volt), de nem igazán akar lebuildelődni.
    A forrás amivel próbálkozom s ami parancssori masm.exe-vel plusz link.exe linkerrel simán fordul s fut: [link]
    VS ezeket a hibákat dobja: [link]

    Mert a példaprogramod 16 bites dos kód, a vs alá meg 32 bites windows kód kell. Szerintem.

  • birno
    addikt

    Sziasztok,

    Visual Studio 2010-et akarnám összelőni, hogy lehessen vele assembly-t fordítani, ezen s ehhez hasonló tutorialok alapján(kb. mindbe ugyanaz volt), de nem igazán akar lebuildelődni.
    A forrás amivel próbálkozom s ami parancssori masm.exe-vel plusz link.exe linkerrel simán fordul s fut: [link]
    VS ezeket a hibákat dobja: [link]

  • C^^
    őstag

    Jajj, DOS :Y

    Amennyire én tudom a parancssor nem 82-től hanem már 81-től kezdődik. A második esetben rögtön a lezáró enterrel amit te éppen nem nézel meg ezért látod az előző parancssor végét.

    Közben meglett: az volt a NAGYOBB hiba, hogy a nagy jumpolgatások között volt egy olyan "ág", ahol a drága programom átugrotta a szegmensek beállítására vonatkozó részt. :D

    Köszönöm egyébként a segítséget, valóban 81-től indexelődik a parancssorról bevitt paraméterlista. Ha lekezelem az üres entert, mint paraméter, akkor működik.

  • Jester01
    veterán

    Sziasztok,

    Indítási paraméter feldolgozással akadt gondom.
    Még a kódszegmensem elején mov di, 82h-val elmentem di-be a PSP kezdőcímét, majd feldolgozom a paramétert.
    Ez működik is, például /?-re egy help szöveget ír ki a program, viszont ha közvetlen ezután paraméter nélkül indítom, akkor egy default értékkel kellene lefutnia a programnak, azonban megint megjelenik a help szöveg, tehát olyan, mintha beragadna a PSP-be az előbbi futás közben átadott paraméter.
    Jól gondolom, hogy nem törlődik futás után a PSP tartalma? Van erre valami megoldás?

    Köszönöm.

    Jajj, DOS :Y

    Amennyire én tudom a parancssor nem 82-től hanem már 81-től kezdődik. A második esetben rögtön a lezáró enterrel amit te éppen nem nézel meg ezért látod az előző parancssor végét.

  • C^^
    őstag

    Sziasztok,

    Indítási paraméter feldolgozással akadt gondom.
    Még a kódszegmensem elején mov di, 82h-val elmentem di-be a PSP kezdőcímét, majd feldolgozom a paramétert.
    Ez működik is, például /?-re egy help szöveget ír ki a program, viszont ha közvetlen ezután paraméter nélkül indítom, akkor egy default értékkel kellene lefutnia a programnak, azonban megint megjelenik a help szöveg, tehát olyan, mintha beragadna a PSP-be az előbbi futás közben átadott paraméter.
    Jól gondolom, hogy nem törlődik futás után a PSP tartalma? Van erre valami megoldás?

    Köszönöm.

  • Dj Sügi
    őstag

    Akia kérdéseket kitalálta nem nagyon áll a helyzet magaslatán, mivel a fixpontos kifejezés a tört/egész bitek megadása nélkül értelmetlen. Úgy tűnik az egész számokra használja inkább, a továbbiakban ezt feltételezem.

    Ezzel együtt az első kettőhöz csak az adott formátumot kell ismerni.
    Az n bites kettes komplemens számábrázolás a nemnegatív számokat önmagukra képezi le, míg a negatív számok 2^n + x képlettel számíthatók. Az értékkészlet -(2^(n-1))..(2^(n-1)-1). Például 16 biten -32768..32767. A legfelső bit jelzi a negatív számokat (előjelbit).

    Az IEE754 formátum exponenciális alakot használ. 32 biten 1 bit előjel, 8 bit kitevő, 23 bit mantissza. A képlet (-1)^s * (1.m)₂ * 2^(e - 127) ahol s az előjel, m a mantissza és e a kitevő.

    1.
    a) Az elmondottak alapján 2^16-31744=33792=8400₁₆
    b) A visszafelé irányhoz megkeressük a kívánt számnál kisebb kettő hatványt és ezzel felbontjuk 48.5=1.515625*32=1.100001₂ * 2^5, innen a kitevő e=5+127=132=10000100₂ a mantissza m=10000100000000000000000₂. Az előjel s=0. Ezeket szépen egymás után írjuk, így az eredmény 42420000₁₆

    2.
    a) Mivel a legfelső bit 1 így ez egy negatív szám, alkalmazzuk rá a képletet: 2^n + x = BF20₁₆ tehát x = -(2^n - BF20₁₆) = -(10000₁₆ - BF20₁₆) = -40E0₁₆ = -16608
    b) a BF200000₁₆=10111111001000000000000000000000₂ értéket bontsuk részeire: s=1, e=01111110₂=126, m=01000000000000000000000₂ majd alkalmazzuk a képletet: x = (-1)^s * (1.m)₂ * 2^(e - 127) = -1 * 1.01₂ * 2 ^ (-1) = -0.625

    3. Lehet rendesen osztani IDIV használatával vagy 4 bittel jobbra eltolni SAR használatával vagy lehet egy táblázatot használni. Egy utasítással ezek jutnak hirtelen az eszembe. Ha több utasítást is lehet írni, akkor át lehet konvertálni előjel nélkülivé és úgy osztani majd visszalakítani, át lehet alakítani lebegőpontossá és FPU vagy SSE osztást végzeni.

    Nagyon köszönöm a segítséget. :R
    Holnap átrágom magam rajta, mert sajna csak akkor lesz időm. Van még pár ilyen példám, ez alapján megpróbálom egyedül megoldani! Aztán átdobom az eredményeket PÜ-ben, esetleg ránézhetnél, hogy jók lettek-e, ha nem túl nagy kérés...?

  • Jester01
    veterán

    Kérnék egy kis segítség, jó lenne, ha ezekből a feladatokból megértenék bármit is:
    (Egy kis magyarázat kellene, hogy mi mit jelent és hogy hasonló feladatokat tudjak legalább értelmezni, megoldani)

    1. Adja meg
    a) a –31744 decimális szám 2 bájtos fixpontos, kettes komplemens, illetve
    b) a 48,5 decimális szám 4 bájtos lebegőpontos (IEEE 754) reprezentációját!

    2. Milyen információt jelent számunkra
    a) a BF20 kétbájtos adat, ha előjeles fixpontos, kettes komplemens, illetve
    b) a BF200000 négybájtos adat, ha lebegőpontos (IEEE 754) reprezentációban értelmezzük?

    3. Adjon meg minél több módszert assembly nyelven egy EAX-ben tárolt fixpontos
    előjeles egész szám 16-tal való osztására!

    Köszönöm! :R

    Akia kérdéseket kitalálta nem nagyon áll a helyzet magaslatán, mivel a fixpontos kifejezés a tört/egész bitek megadása nélkül értelmetlen. Úgy tűnik az egész számokra használja inkább, a továbbiakban ezt feltételezem.

    Ezzel együtt az első kettőhöz csak az adott formátumot kell ismerni.
    Az n bites kettes komplemens számábrázolás a nemnegatív számokat önmagukra képezi le, míg a negatív számok 2^n + x képlettel számíthatók. Az értékkészlet -(2^(n-1))..(2^(n-1)-1). Például 16 biten -32768..32767. A legfelső bit jelzi a negatív számokat (előjelbit).

    Az IEE754 formátum exponenciális alakot használ. 32 biten 1 bit előjel, 8 bit kitevő, 23 bit mantissza. A képlet (-1)^s * (1.m)₂ * 2^(e - 127) ahol s az előjel, m a mantissza és e a kitevő.

    1.
    a) Az elmondottak alapján 2^16-31744=33792=8400₁₆
    b) A visszafelé irányhoz megkeressük a kívánt számnál kisebb kettő hatványt és ezzel felbontjuk 48.5=1.515625*32=1.100001₂ * 2^5, innen a kitevő e=5+127=132=10000100₂ a mantissza m=10000100000000000000000₂. Az előjel s=0. Ezeket szépen egymás után írjuk, így az eredmény 42420000₁₆

    2.
    a) Mivel a legfelső bit 1 így ez egy negatív szám, alkalmazzuk rá a képletet: 2^n + x = BF20₁₆ tehát x = -(2^n - BF20₁₆) = -(10000₁₆ - BF20₁₆) = -40E0₁₆ = -16608
    b) a BF200000₁₆=10111111001000000000000000000000₂ értéket bontsuk részeire: s=1, e=01111110₂=126, m=01000000000000000000000₂ majd alkalmazzuk a képletet: x = (-1)^s * (1.m)₂ * 2^(e - 127) = -1 * 1.01₂ * 2 ^ (-1) = -0.625

    3. Lehet rendesen osztani IDIV használatával vagy 4 bittel jobbra eltolni SAR használatával vagy lehet egy táblázatot használni. Egy utasítással ezek jutnak hirtelen az eszembe. Ha több utasítást is lehet írni, akkor át lehet konvertálni előjel nélkülivé és úgy osztani majd visszalakítani, át lehet alakítani lebegőpontossá és FPU vagy SSE osztást végzeni.

  • Dj Sügi
    őstag

    Kérnék egy kis segítség, jó lenne, ha ezekből a feladatokból megértenék bármit is:
    (Egy kis magyarázat kellene, hogy mi mit jelent és hogy hasonló feladatokat tudjak legalább értelmezni, megoldani)

    1. Adja meg
    a) a –31744 decimális szám 2 bájtos fixpontos, kettes komplemens, illetve
    b) a 48,5 decimális szám 4 bájtos lebegőpontos (IEEE 754) reprezentációját!

    2. Milyen információt jelent számunkra
    a) a BF20 kétbájtos adat, ha előjeles fixpontos, kettes komplemens, illetve
    b) a BF200000 négybájtos adat, ha lebegőpontos (IEEE 754) reprezentációban értelmezzük?

    3. Adjon meg minél több módszert assembly nyelven egy EAX-ben tárolt fixpontos
    előjeles egész szám 16-tal való osztására!

    Köszönöm! :R

  • plaschil
    aktív tag

    Ha egyáltalán fogalmad sincs akkor az kemény menet lesz.
    Először is, az assembly az processzor(-család) specifikus dolog. Az említett 2 feladat 2 különböző processzorra kell. Mindkét esetben szükséged lesz a megfelelő utasításkészlet leírásra (instruction set reference) és persze az általános architektúra ismeretére. Amennyiben ki is akarod őket próbálni, úgy a fejlesztési eszközökre (toolchain) is szükséged lesz, ideértve egy debuggert és egy szimulátort is.

    Egyik feladat megfogalmazása sem egyértelmű, de kiindulásnak jó lesz ha egyfajta értelmezést elfogadunk.

    Nézzük az elsőt. Tegyük fel, hogy úgy értették, azt a 2 konstans számot kell BCD módban összeadni, majd az eredményt binárisan (egy byteon), BCD-ben és hexában (ez utóbbi kettőt ascii kóddal) megadni. A programban először összeadjuk őket binárisan majd a megadott "decimális korrekciót" alkalmazva kapjuk a bcd eredményt. Ezután ezt össze-vissza alakítjuk:
    - a bcd értéket egyesekre (e) és tízesekre (t) bontjuk
    - 00 ascii kódját hozzáadva kapjuk a decimális eredményt
    - 10t+e=8t+t+t+e képlettel kapjuk a bináris eredményt
    - amit pedig két 4 bites részre bontunk, ebből lesz egy-egy hexa számjegy amit táblázatból olvasunk ki

    Íme:

    mov al, 38h
    add al, 49h
    daa ; 38(bcd) + 49(bcd) = 87(bcd)
    mov dh, al ; copy (DH=87h)
    mov dl, al ; copy (DL=87h)
    shr dh, 4 ; tens (DH=08h)
    and dl, 0fh ; ones (DL=07h)
    mov al, dh ; tens (AL=08h)
    shl al, 3 ; 8 * tens (AL=40h)
    add al, dh ; 9 * tens (AL=48h)
    add al, dh ; 10 * tens (AL=50h)
    add al, dl ; 10 * tens + ones (AL=57h=87)
    add dx, 3030h ; convert to ascii (DX=3837h='87')
    movzx bx, al ; copy and zero BH (BX=57h)
    shr bl, 4 ; first hex digit (BX=05h)
    mov ch, [table+bx] ; get hex digit (CH=35h='5')
    mov bl, al ; copy (BX=57h)
    and bx, 0fh ; second hex digit (BX=07h)
    mov cl, [table+bx] ; get hex digit (CL=37h='7')
    ; results
    ; AL=binary (57h)
    ; CX=hex (3537h='57')
    ; DX=dec (3837h='87')

    ; lookup table for hex digits
    table: db '0123456789ABCDEF'

    (a táblázat olvasásnál feltételeztem, hogy CS=DS. Ha ez nem így van, akkor CS: előtag használata szükséges vagy a táblázatot kell a DS szegmensbe tenni.)

    Emésztem, köszönöm szépen! :K

  • Jester01
    veterán

    Bocsánat de halvány lila gőzöm sincs ezeknek a feladatoknak a megoldásáról, ugyanis egész félévben kb. csak KV tábláztunk. :U
    Ha egyet-kettőt látnék megoldva, hogy pl. soronként mi a bánatot csinál, akkor talán könnyebben menne a megértése ezeknek a feladatoknak.

    De megfelel nekem az is hogyha segítetek, hogyan induljak neki egy ilyen feladat megoldásának. Egyáltalán mik szükségesek hozzá. Az se baj ha angol nyelvű.

    Ha egyáltalán fogalmad sincs akkor az kemény menet lesz.
    Először is, az assembly az processzor(-család) specifikus dolog. Az említett 2 feladat 2 különböző processzorra kell. Mindkét esetben szükséged lesz a megfelelő utasításkészlet leírásra (instruction set reference) és persze az általános architektúra ismeretére. Amennyiben ki is akarod őket próbálni, úgy a fejlesztési eszközökre (toolchain) is szükséged lesz, ideértve egy debuggert és egy szimulátort is.

    Egyik feladat megfogalmazása sem egyértelmű, de kiindulásnak jó lesz ha egyfajta értelmezést elfogadunk.

    Nézzük az elsőt. Tegyük fel, hogy úgy értették, azt a 2 konstans számot kell BCD módban összeadni, majd az eredményt binárisan (egy byteon), BCD-ben és hexában (ez utóbbi kettőt ascii kóddal) megadni. A programban először összeadjuk őket binárisan majd a megadott "decimális korrekciót" alkalmazva kapjuk a bcd eredményt. Ezután ezt össze-vissza alakítjuk:
    - a bcd értéket egyesekre (e) és tízesekre (t) bontjuk
    - 00 ascii kódját hozzáadva kapjuk a decimális eredményt
    - 10t+e=8t+t+t+e képlettel kapjuk a bináris eredményt
    - amit pedig két 4 bites részre bontunk, ebből lesz egy-egy hexa számjegy amit táblázatból olvasunk ki

    Íme:

    mov al, 38h
    add al, 49h
    daa ; 38(bcd) + 49(bcd) = 87(bcd)
    mov dh, al ; copy (DH=87h)
    mov dl, al ; copy (DL=87h)
    shr dh, 4 ; tens (DH=08h)
    and dl, 0fh ; ones (DL=07h)
    mov al, dh ; tens (AL=08h)
    shl al, 3 ; 8 * tens (AL=40h)
    add al, dh ; 9 * tens (AL=48h)
    add al, dh ; 10 * tens (AL=50h)
    add al, dl ; 10 * tens + ones (AL=57h=87)
    add dx, 3030h ; convert to ascii (DX=3837h='87')
    movzx bx, al ; copy and zero BH (BX=57h)
    shr bl, 4 ; first hex digit (BX=05h)
    mov ch, [table+bx] ; get hex digit (CH=35h='5')
    mov bl, al ; copy (BX=57h)
    and bx, 0fh ; second hex digit (BX=07h)
    mov cl, [table+bx] ; get hex digit (CL=37h='7')
    ; results
    ; AL=binary (57h)
    ; CX=hex (3537h='57')
    ; DX=dec (3837h='87')

    ; lookup table for hex digits
    table: db '0123456789ABCDEF'

    (a táblázat olvasásnál feltételeztem, hogy CS=DS. Ha ez nem így van, akkor CS: előtag használata szükséges vagy a táblázatot kell a DS szegmensbe tenni.)

  • plaschil
    aktív tag

    Meg, de inkább segíteni szoktunk.

    Bocsánat de halvány lila gőzöm sincs ezeknek a feladatoknak a megoldásáról, ugyanis egész félévben kb. csak KV tábláztunk. :U
    Ha egyet-kettőt látnék megoldva, hogy pl. soronként mi a bánatot csinál, akkor talán könnyebben menne a megértése ezeknek a feladatoknak.

    De megfelel nekem az is hogyha segítetek, hogyan induljak neki egy ilyen feladat megoldásának. Egyáltalán mik szükségesek hozzá. Az se baj ha angol nyelvű.

  • Jester01
    veterán

    Sziasztok!

    Az alábbi feladatokat valaki meg tudná nekem oldani?

    1. 8086-os mikroprocesszorral kellene egy programot írni, ami a 38h adathoz hozzáadja a 49h adatot. Használni kellene decimális korrekciót és az eredményt binárisan, hexában és decimálisan is meg kellene adni.

    2. program készítés 4 bites GRAY kódú hanggenerátorra 8085 mikroprocesszorral. A kijelzést a 06h portra küldje. Az időzítés legyen fix, értéke FABCh. (használjon memóriatáblázatot)

    Köszi a segítséget! :R

    Meg, de inkább segíteni szoktunk.

  • plaschil
    aktív tag

    Sziasztok!

    Az alábbi feladatokat valaki meg tudná nekem oldani?

    1. 8086-os mikroprocesszorral kellene egy programot írni, ami a 38h adathoz hozzáadja a 49h adatot. Használni kellene decimális korrekciót és az eredményt binárisan, hexában és decimálisan is meg kellene adni.

    2. program készítés 4 bites GRAY kódú hanggenerátorra 8085 mikroprocesszorral. A kijelzést a 06h portra küldje. Az időzítés legyen fix, értéke FABCh. (használjon memóriatáblázatot)

    Köszi a segítséget! :R

  • zka67
    őstag

    8051-es mikrokontroller programozáshoz kell, azaz Intel.

    Van egy nagyon jó ingyenes program a 8051-es mikrokontroller családhoz, amivel az áramkör megépítése nélkül ki is tudod próbálni a programod működését. Turbo Pascal-ban és Assembler-ben is tudsz vele programot írni, van benne szimulátor, debugger, terminál, oszcilloszkóp meg még rengeteg hasznos dolog.

    Turbo51 Studio

  • Dark Archon
    addikt

    Ott XRL-nek hívják, tehát sztanozs kolléga útmutatása alapján XRL A, #0xff

    MOD: ja most látom még CPL is van, szóval egyszerűen CPL A

    Köszönöm :R

  • Jester01
    veterán

    8051-es mikrokontroller programozáshoz kell, azaz Intel.

    Ott XRL-nek hívják, tehát sztanozs kolléga útmutatása alapján XRL A, #0xff

    MOD: ja most látom még CPL is van, szóval egyszerűen CPL A

  • Dark Archon
    addikt

    Milyen architektúrán?
    NOT ACC nincs? (esetleg XOR ACC, 0xFF?)

    8051-es mikrokontroller programozáshoz kell, azaz Intel.

  • sztanozs
    veterán

    Kicsit döglöttnek néz ki a topic, de azért kérdeznék:

    Teszem azt, az acc regiszterben van 8 bit adat. Hogyan lehet egyszerűen invertálni minden bitet? Tehát pl., hogy 00001000 helyett 11110111 legyen. Keresgéltem neten, de úgy tűnik nincs ilyen assembly parancs.

    Milyen architektúrán?
    NOT ACC nincs? (esetleg XOR ACC, 0xFF?)

  • Dark Archon
    addikt

    Kicsit döglöttnek néz ki a topic, de azért kérdeznék:

    Teszem azt, az acc regiszterben van 8 bit adat. Hogyan lehet egyszerűen invertálni minden bitet? Tehát pl., hogy 00001000 helyett 11110111 legyen. Keresgéltem neten, de úgy tűnik nincs ilyen assembly parancs.

  • sonar
    addikt

    Debugger gui létezik, de azokban tipikusan nem tudod szerkeszteni és fordítani a kódot, tehát nem ide a szokásos értelemben. Mondjuk architektúrát sem írtál.

    Sima x86 érdekelne. De ha létezik ARM-re vagy másra azt is szívesen kipróbálnám.

  • Jester01
    veterán

    Sziasztok,

    Linux alá létezik valami jó kis IDE környezet?
    (Nem szöveg szerkesztőre gondoltam, hanem olyan amivel lehet soronként léptetni a kódot és kiiratni a regiszterek tartalmát etc...)

    Debugger gui létezik, de azokban tipikusan nem tudod szerkeszteni és fordítani a kódot, tehát nem ide a szokásos értelemben. Mondjuk architektúrát sem írtál.

  • sonar
    addikt

    Sziasztok,

    Linux alá létezik valami jó kis IDE környezet?
    (Nem szöveg szerkesztőre gondoltam, hanem olyan amivel lehet soronként léptetni a kódot és kiiratni a regiszterek tartalmát etc...)

  • Jester01
    veterán

    Hali!

    Ez nem konkrétan asm kérdés, csak gondoltam valószínűleg azzal (is) meg lehet oldani, emelett akik ide írnak, igencsak benne vannak a témában úgy általában, szóval reményeim szerint a sikerre is nagyobb az esélyem.

    Következő a problémám, amit szeretnék megoldani:

    A merevlemezről szeretném a bootolásért felelős részt áthelyezni egy másik eszközre, leginkább pendrive-ra és az eredeti helyéről pedig letörölni, majd azt elérni, hogy amikor erről a pendrive-ról bootolok, akkor azt a rendszert tudjam indítani, amihez az áthelyzett bootkód eredetileg "illett".

    Megoldható az MBR assembly-jéne átírásával esetleg?
    Bevallom még nem néztem utána, hogy hogyan működik a bootolás ilyen részleteiben.

    Ha valakinek esetleg lenne ötlete, vagy ismerne már kész szoftvert, amivel ezt meg lehet oldani, akkor hálás lennék, ha megosztaná.

    Kösz!

    Ilyet a különféle boot managerek tudnak, például lilo vagy grub:
    "Alternatively, GRUB can pass control of the boot process to another loader, using chain loading. This is the method used to load operating systems such as Windows, that do not support the Multiboot standard or are not supported directly by GRUB. In this case, copies of the other system's boot programs have been saved by GRUB. Instead of a kernel, the other system is loaded as though it had been started from the MBR."

  • Smells
    tag

    Hali!

    Ez nem konkrétan asm kérdés, csak gondoltam valószínűleg azzal (is) meg lehet oldani, emelett akik ide írnak, igencsak benne vannak a témában úgy általában, szóval reményeim szerint a sikerre is nagyobb az esélyem.

    Következő a problémám, amit szeretnék megoldani:

    A merevlemezről szeretném a bootolásért felelős részt áthelyezni egy másik eszközre, leginkább pendrive-ra és az eredeti helyéről pedig letörölni, majd azt elérni, hogy amikor erről a pendrive-ról bootolok, akkor azt a rendszert tudjam indítani, amihez az áthelyzett bootkód eredetileg "illett".

    Megoldható az MBR assembly-jéne átírásával esetleg?
    Bevallom még nem néztem utána, hogy hogyan működik a bootolás ilyen részleteiben.

    Ha valakinek esetleg lenne ötlete, vagy ismerne már kész szoftvert, amivel ezt meg lehet oldani, akkor hálás lennék, ha megosztaná.

    Kösz!

  • CPT.Pirk
    Jómunkásember

    Azért, mert MOV A, #SZOVEG van a ciklusban mindig. Egyébként a MOV 3, #KERES is rossz, mert az a címet tölti be, nem pedig az első karaktert. Valami ilyesmi kellene az elejére:

    MOV R0, #SZOVEG ; R0-ba pointert töltünk
    MOV R3, KERES ; itt nincs # jel, memória olvasás
    loop1:
    MOV A, @R0 ; itt olvassuk a szöveg következő betűjét

    Köszi, így már szépen keres, és talál is. :R
    Az az egyetlen probléma, hogy a találat mögötti karakterek helyét adja vissza. Próbálkoztam pár dolog DEC -rementálásával, de nem akar stimmelni.

  • Jester01
    veterán

    No most kicsit megint kérnék segítséget. Igyekeztem szimulálni, használni változókat hozzá, a fordító szerint nincs errorom, Viszont nem akar kijutni az első XLR-es ciklusból, pedig jónak néz ki a kód. Egyenlőre itt tart a kód: [link]

    Azért, mert MOV A, #SZOVEG van a ciklusban mindig. Egyébként a MOV 3, #KERES is rossz, mert az a címet tölti be, nem pedig az első karaktert. Valami ilyesmi kellene az elejére:

    MOV R0, #SZOVEG ; R0-ba pointert töltünk
    MOV R3, KERES ; itt nincs # jel, memória olvasás
    loop1:
    MOV A, @R0 ; itt olvassuk a szöveg következő betűjét

  • CPT.Pirk
    Jómunkásember

    Igen, ez lenne a logika, csak elrontottam :B
    A második utasítás MOV 3, R1 helyett MOV R3, A kellene legyen persze, hiszen az akkumulátorba töltöttem a betűt. Sőt, tulajdonképpen ezt egyből is meg lehet tenni: MOV 3, @R1

    No most kicsit megint kérnék segítséget. Igyekeztem szimulálni, használni változókat hozzá, a fordító szerint nincs errorom, Viszont nem akar kijutni az első XLR-es ciklusból, pedig jónak néz ki a kód. Egyenlőre itt tart a kód: [link]

  • Jester01
    veterán

    No, akkor megnézve ezt, ha jól értem ez történik:

    Először:
    @R1 pointer által mutatott memóriahelyen lévő érték bekerül az akkumulátorba, valamint elmentjük a "tű" első és második karakterét.

    Aztán belépve az első ciklusba, először jön egy nulla vizsgálat, aztán ha nem nulla az Akku tartalma (@R0), akkor jön egy kizáró vagy kapcsolat, ami az AKKU és R3 nem egyezése esetén újraindítja a ciklust és közben arrébb teszi R0-át.
    Mikor megvan az első egyezés, akkor az R1 megkapja a "tű" második karakterét, valamint elmenti a "szénakazal" aktuális karakterét R4-be, és jön a ciklus 2.

    A második ciklus először betölti a szénakazal karakterét az akkuba, majd xor relációval megnézi, hogy egyeznek-e, ha nem, akkor kiugrik a mismatch ágra, és a szénakazal aktuális karakterétől kezdi újra keresni a loop2 az egyezéseket.
    Ha nem ugrott ki, akkor jön egy lezáró nulla keresés, majd ha megvan, és mindvégig egyezés volt, akkor visszaadja R0-ban a kazal első egyező karakterét, vagy annak helyét.

    Köszönöm a segítséget. :R

    Igen, ez lenne a logika, csak elrontottam :B
    A második utasítás MOV 3, R1 helyett MOV R3, A kellene legyen persze, hiszen az akkumulátorba töltöttem a betűt. Sőt, tulajdonképpen ezt egyből is meg lehet tenni: MOV 3, @R1

  • CPT.Pirk
    Jómunkásember

    .org 0x30
    ; strstr
    ; IN: R0=haystack, R1=needle (both zero terminated)
    ; OUT: R0=start (points to end of haystack if not found)
    ; DESTROYED: ACC, R2, R3, R4

    MOV A, @R1 ; 1st char of needle
    MOV 3, R1 ; save a copy
    INC R1
    MOV 2, R1

    loop1:
    MOV A, @R0
    JZ done
    XRL A, R3
    INC R0
    JNZ loop1
    MOV 1, R2 ; needle 2nd char ptr
    MOV 4, R0 ; save haystack
    loop2:
    MOV A, @R0 ; next haystack
    XRL A, @R1 ; next needle
    JNZ mismatch
    MOV A, @R0 ; check for terminator
    INC R0
    INC R1
    JNZ loop2
    MOV 0, R4 ; restore haystack
    DEC R0 ; adjust to 1st char
    done:
    RET
    mismatch:
    MOV 0, R4 ; restore haystack
    AJMP loop1

    Fogalmam sincs működik-e, most nincs kedvem kipróbálni :P

    No, akkor megnézve ezt, ha jól értem ez történik:

    Először:
    @R1 pointer által mutatott memóriahelyen lévő érték bekerül az akkumulátorba, valamint elmentjük a "tű" első és második karakterét.

    Aztán belépve az első ciklusba, először jön egy nulla vizsgálat, aztán ha nem nulla az Akku tartalma (@R0), akkor jön egy kizáró vagy kapcsolat, ami az AKKU és R3 nem egyezése esetén újraindítja a ciklust és közben arrébb teszi R0-át.
    Mikor megvan az első egyezés, akkor az R1 megkapja a "tű" második karakterét, valamint elmenti a "szénakazal" aktuális karakterét R4-be, és jön a ciklus 2.

    A második ciklus először betölti a szénakazal karakterét az akkuba, majd xor relációval megnézi, hogy egyeznek-e, ha nem, akkor kiugrik a mismatch ágra, és a szénakazal aktuális karakterétől kezdi újra keresni a loop2 az egyezéseket.
    Ha nem ugrott ki, akkor jön egy lezáró nulla keresés, majd ha megvan, és mindvégig egyezés volt, akkor visszaadja R0-ban a kazal első egyező karakterét, vagy annak helyét.

    Köszönöm a segítséget. :R

  • Jester01
    veterán

    Hol találok 8051 c libraryt? Már pár napja túrom a google-t, de vagy nem értek hozzá, vagy nem tudom miért, de nem találok semmi ilyesmit.

    Az strstr fgv sima C-s implementációját sem találtam meg, mindenhol csak egy példával be van mutatva, hogyan kell használni, aztán csókolom. Amiket találtam, azok meg házi kódok, de mindben van valami hiba, pl. egyéb string függvény hívások, stb.

    Továbbra is az a gondom, hogy sajnos nem tudom magamtól megírni ezt az egyszerű függvényt, folyamatábrát megrajzoltam, működését értem, de hogy pl. egy memóriaterületre mutató pointert hogyan kellene megcsinálni 8051-es Assembly-n, meg léptetni arrébb, stb., na az kínai nekem.

    szerk: csak nem ezt fordítottad le?

    #include <stdio.h>

    const char *mystrstr(const char *haystack, const char *needle)
    {
    if ( !*needle )
    {
    return haystack;
    }
    for ( ; *haystack; ++haystack )
    {
    if ( *haystack == *needle )
    {
    /*
    * Matched starting char -- loop through remaining chars.
    */
    const char *h, *n;
    for ( h = haystack, n = needle; *h && *n; ++h, ++n )
    {
    if ( *h != *n )
    {
    break;
    }
    }
    if ( !*n ) /* matched all of 'needle' to null termination */
    {
    return haystack; /* return the start of the match */
    }
    }
    }
    return 0;
    }

    int main(void)
    {
    const char text[] = "The quick brown fox jumps over the lazy dog.";
    const char word[] = "fox";
    const char *found = mystrstr(text, word);
    if ( found )
    {
    puts(found);
    }
    return 0;
    }

    Nem azt fordítottam le, kézzel csináltam a kódot. Ha konkrét kérdésed van, arra szívesen válaszolok. Lássuk azt a kettőt ami a hszben van:

    memóriaterületre mutató pointert hogyan kellene megcsinálni

    Indirekcióra az R0 és R1 használható egyszerűen.

    MOV R0, #pointer
    MOV A, @R0

    meg léptetni arrébb

    Ez meg pofon egyszerű: INC R0
    Gondolom utasításlistád az van.

    C library meg gondolom az sdcc-hez jár.

  • CPT.Pirk
    Jómunkásember

    Ez eleve hiányos kód, mivel a first_char_found sehol nincs benne és dl sincs inicializálva. Különben semmi extrát nem csinál, csak megkeresi az első betű egyezést és utána ellenőrzi a többit. Teljesen fölösleges lenne az assembly változatot átküzdeni 8051-re, sokkal egyszerűbb az alap algoritmust implementálni. Vagy fogni egy 8051 c libraryt és kimásolni ;)

    Hol találok 8051 c libraryt? Már pár napja túrom a google-t, de vagy nem értek hozzá, vagy nem tudom miért, de nem találok semmi ilyesmit.

    Az strstr fgv sima C-s implementációját sem találtam meg, mindenhol csak egy példával be van mutatva, hogyan kell használni, aztán csókolom. Amiket találtam, azok meg házi kódok, de mindben van valami hiba, pl. egyéb string függvény hívások, stb.

    Továbbra is az a gondom, hogy sajnos nem tudom magamtól megírni ezt az egyszerű függvényt, folyamatábrát megrajzoltam, működését értem, de hogy pl. egy memóriaterületre mutató pointert hogyan kellene megcsinálni 8051-es Assembly-n, meg léptetni arrébb, stb., na az kínai nekem.

    szerk: csak nem ezt fordítottad le?

    #include <stdio.h>

    const char *mystrstr(const char *haystack, const char *needle)
    {
    if ( !*needle )
    {
    return haystack;
    }
    for ( ; *haystack; ++haystack )
    {
    if ( *haystack == *needle )
    {
    /*
    * Matched starting char -- loop through remaining chars.
    */
    const char *h, *n;
    for ( h = haystack, n = needle; *h && *n; ++h, ++n )
    {
    if ( *h != *n )
    {
    break;
    }
    }
    if ( !*n ) /* matched all of 'needle' to null termination */
    {
    return haystack; /* return the start of the match */
    }
    }
    }
    return 0;
    }

    int main(void)
    {
    const char text[] = "The quick brown fox jumps over the lazy dog.";
    const char word[] = "fox";
    const char *found = mystrstr(text, word);
    if ( found )
    {
    puts(found);
    }
    return 0;
    }

  • Jester01
    veterán

    Ez eleve hiányos kód, mivel a first_char_found sehol nincs benne és dl sincs inicializálva. Különben semmi extrát nem csinál, csak megkeresi az első betű egyezést és utána ellenőrzi a többit. Teljesen fölösleges lenne az assembly változatot átküzdeni 8051-re, sokkal egyszerűbb az alap algoritmust implementálni. Vagy fogni egy 8051 c libraryt és kimásolni ;)

    .org 0x30
    ; strstr
    ; IN: R0=haystack, R1=needle (both zero terminated)
    ; OUT: R0=start (points to end of haystack if not found)
    ; DESTROYED: ACC, R2, R3, R4

    MOV A, @R1 ; 1st char of needle
    MOV 3, R1 ; save a copy
    INC R1
    MOV 2, R1

    loop1:
    MOV A, @R0
    JZ done
    XRL A, R3
    INC R0
    JNZ loop1
    MOV 1, R2 ; needle 2nd char ptr
    MOV 4, R0 ; save haystack
    loop2:
    MOV A, @R0 ; next haystack
    XRL A, @R1 ; next needle
    JNZ mismatch
    MOV A, @R0 ; check for terminator
    INC R0
    INC R1
    JNZ loop2
    MOV 0, R4 ; restore haystack
    DEC R0 ; adjust to 1st char
    done:
    RET
    mismatch:
    MOV 0, R4 ; restore haystack
    AJMP loop1

    Fogalmam sincs működik-e, most nincs kedvem kipróbálni :P

  • Jester01
    veterán

    Tudnátok nekem segíteni egy kicsit?

    Egy string kereső programot kellene átalakítani úgy, hogy kompatibilis legyen 8051-es mikrovezérlők utasításkészletével, regisztereivel.

    A kód PC-s verziója így néz ki:

    findnext:
    mov esi,edi ; esi = edi = pointers to somewhere in str1
    mov ecx,[esp + 14h] ; str2

    ;use edi instead of esi to eliminate AGI
    mov al,[edi] ; al is next char from str1

    add esi,1 ; increment pointer into str1

    cmp al,dl
    je first_char_found

    test al,al ; end of str1?
    jz not_found ; yes, and no match has been found

    loop_start:
    mov al,[esi] ; put next char from str1 into al
    add esi,1 ; increment pointer in str1
    in_loop:
    cmp al,dl
    je first_char_found

    test al,al ; end of str1?
    jnz loop_start ; no, go get another char from str1

    not_found:
    pop esi
    pop ebx
    pop edi
    xor eax,eax
    ret

    Ez egyébként elvileg a C-s strstr függvény is egyben. A kód innen származik: [link]

    Ez eleve hiányos kód, mivel a first_char_found sehol nincs benne és dl sincs inicializálva. Különben semmi extrát nem csinál, csak megkeresi az első betű egyezést és utána ellenőrzi a többit. Teljesen fölösleges lenne az assembly változatot átküzdeni 8051-re, sokkal egyszerűbb az alap algoritmust implementálni. Vagy fogni egy 8051 c libraryt és kimásolni ;)

  • CPT.Pirk
    Jómunkásember

    Tudnátok nekem segíteni egy kicsit?

    Egy string kereső programot kellene átalakítani úgy, hogy kompatibilis legyen 8051-es mikrovezérlők utasításkészletével, regisztereivel.

    A kód PC-s verziója így néz ki:

    findnext:
    mov esi,edi ; esi = edi = pointers to somewhere in str1
    mov ecx,[esp + 14h] ; str2

    ;use edi instead of esi to eliminate AGI
    mov al,[edi] ; al is next char from str1

    add esi,1 ; increment pointer into str1

    cmp al,dl
    je first_char_found

    test al,al ; end of str1?
    jz not_found ; yes, and no match has been found

    loop_start:
    mov al,[esi] ; put next char from str1 into al
    add esi,1 ; increment pointer in str1
    in_loop:
    cmp al,dl
    je first_char_found

    test al,al ; end of str1?
    jnz loop_start ; no, go get another char from str1

    not_found:
    pop esi
    pop ebx
    pop edi
    xor eax,eax
    ret

    Ez egyébként elvileg a C-s strstr függvény is egyben. A kód innen származik: [link]

  • Atisch
    csendes tag

    Na jó, kezdek szomorú lenni, hogy nem értek hozzá. Átírtam, viszont valamiért nem ad helyes eredményt, olyat is nem anagrammának ír, ami nem az :( pl alma lama, holott ez anagramma kéne legyen. Nem látom hol a hiba :(

    A lényege, hogy a 2szóban lévő megegyezőket kinullázza, és utána megnézi, hogy egyezik e (tehát mind 0, az 1es azért van ott a szavak végén, hogy jelezze, hogy ne végtelen legye,
    szo1 db 0,0,0,0...0,0,0,1
    ; 1. vizsgálat:

    XOR AX,AX ; Kinullázzuk
    XOR BX,BX ; Kinullázzuk
    XOR SI,SI ; Kinullázzuk

    CIKLUS:

    MOV AH, [szo1 + BX] ;Betöltjök AH-be a szo1 0,1,2,3....39ik bytját
    MOV AL, [szo2 + SI] ;Betöltjök AL-be a szo2 0,1,2,3....39ik bytját

    CMP AH, 1 ; Mindig megnézzük utolsó lépés e ez. Utolsó betű e?
    JE CIKLUS2 ; Elugrunk a másik CIKLUSBA, végeztünk az első lépéssel.

    CMP AH,AL ; Összehasonlítjuk a tartalmat
    JE NULL ; Ha 0, tehát egyenlők
    JNE ROSSZ ; Ha különböznek

    ROSSZ: ; Ha nem egyezik a két betű
    CMP AL, 1
    JE HELYESBIT
    INC SI ; Növeljük a regisztert
    JMP CIKLUS ; Ugrunk a következő karakterre

    HELYESBIT:
    XOR SI,SI ; 0-ra álítjuk, hogy előröl induljon
    INC BX ; Az első szó második lépésére
    JMP CIKLUS

    NULL:
    MOV szo1[BX], '0' ; Betesszük a szo1 BX-ben tárolt helyére a '0' értéket
    MOV szo2[SI], '0' ; Betesszük a szo2 CX-ben tárolt helyére a '0' értéket
    INC BX ; Novelunk
    INC SI ; Novelunk
    JMP CIKLUS

    ;2. vizsgálat:

    XOR AX,AX ; Kinullázzuk
    XOR BX,BX ; Kinullázzuk
    XOR SI,SI ; Kinullázzuk

    CIKLUS2:
    MOV AH, [szo2 + BX] ;Betöltjök AH-be a szo1 0,1,2,3....39ik bytját
    MOV AL, [szo1 + SI] ;Betöltjök AL-be a szo2 0,1,2,3....39ik bytját

    CMP AH, 1 ; Mindig megnézzük utolsó lépés e ez.
    JE DONTES ; Elugrunk a másik CIKLUSBA

    CMP AH,AL ; Összehasonlítjuk a tartalmat
    JE NULL2 ; Ha 0, tehát egyenlők
    JNE ROSSZ2 ; Ha különböznek

    ROSSZ2: ; Ha nem egyezik a két betű
    CMP AL, 1
    JE HELYESBIT2
    INC SI ; Növeljük a regisztert
    JMP CIKLUS2 ; Ugrunk a következő karakterre

    HELYESBIT2:
    XOR SI,SI ; 0-ra álítjuk, hogy előröl induljon
    INC BX ; Az első szó második lépésére
    JMP CIKLUS2

    NULL2:
    MOV szo2[BX], '0' ; Betesszük a szo1 BX-ben tárolt helyére a '0' értéket
    MOV szo1[SI], '0' ; Betesszük a szo2 CX-ben tárolt helyére a '0' értéket
    INC BX ; Novelunk
    INC SI ; Novelunk
    JMP CIKLUS2

    ;3. Lépés:

    DONTES:
    MOV SI, OFFSET szo1 ; Kialakított szó
    MOV DI, OFFSET szo2 ; Másik kialakított szó
    CMPSB
    JE ANAGRAIGEN
    JNE ANAGRANEM

    ;------------------------------------------------------
    ; Végső kiírások (eredmény):

    ANAGRANEM:

    CALL ujsor
    MOV SI, offset szoveg6 ; Nem Anagramma
    CALL kiiro

    RET ; Visszatérés az op. rendszerhez

    ANAGRAIGEN:

    CALL ujsor
    MOV SI, offset szoveg5 ; Anagramma
    CALL kiiro

    RET ; Visszatérés az op. rendszerhez

    és sikerült megoldanod?

  • Sziasztok

    A napokban kaptam egy olyan feladatot assemblyben hogy nagy számokat kell összeszorozni.Maximum 10 jegyű két darab számot kell.Szeretnék kérni egy kis kiindulási pontot.Szerintem úgy lenne a legegyszerűbb ahogy papíron szorzunk:
    123 x 456
    ---
    492
    615
    738
    -----
    56088

    Valakinek még valami ötlet?

    üdv bolvar

  • zka67
    őstag

    Köszi!

    A 2. feladatban az a lényeg, hogy 8 eszközt kell pwm vezérelni (0-127 a lehetséges értékek), miközben a mikrovezérlőknek legfeljebb 6 vezérlésére van lehetőségük, de mégis egy vezérlővel kellene 8 eszközt működtetni. A bemenet pedig egy 8*8 bites számsor.

    Itt igazából az a gond, hogy nem tudjuk, mit kellene csinálni.

    PÜ-ben ment a program.

  • zka67
    őstag

    Köszi!

    A 2. feladatban az a lényeg, hogy 8 eszközt kell pwm vezérelni (0-127 a lehetséges értékek), miközben a mikrovezérlőknek legfeljebb 6 vezérlésére van lehetőségük, de mégis egy vezérlővel kellene 8 eszközt működtetni. A bemenet pedig egy 8*8 bites számsor.

    Itt igazából az a gond, hogy nem tudjuk, mit kellene csinálni.

    Konkrét típusra kell megcsinálni vagy 8051-re általában? Mert a 8051-nek 4*8 kimenete van.

    Van valami megkötés a frekvenciára?

  • CPT.Pirk
    Jómunkásember

    Az átlagolásod lényegesen egyszerűbben és gyorsabban is megoldható. Ez a szép az assembly nyelvben, hogy többféleképpen is meg lehet írni ugyanazt a programot, csak meg kell tornáztatni az agyat egy kicsit.

    dseg

    org $0030

    adat_buff: ds 16
    atlag: ds 2

    cseg


    ;------------------------------------------------------------------------------
    ; atlagolas - adat_buff atlagolasa.
    ;
    ; input: adat_buff, 16 db 8 bites adattal
    ; output: atlag, a 16 db 8 bites szam atlaga
    ;
    ; felhasznalt regiszterek:
    ; B - temp osszeg felso byte
    ; A - temp osszeg also byte
    ; R0- buffer pointer
    ;------------------------------------------------------------------------------

    atlagolas: clr a ;temp[16] = 0
    mov b,a

    mov R0,#adat_buff ;buffer elejere all
    _1: add a,@R0 ;temp[lo] += adat
    jnc _2 ;tulcsordult?
    inc b ;ha igen, temp[hi] += 1
    _2: inc R0 ;kovetkezo adatra all
    cjne R0,#adat_buff+16,_1 ;mindet osszeadta?

    ;BA shiftelese jobbra 4 bittel (osztas 16-al)
    ;mivel 16 db 8 bites szamot ad ossze, ezert B felso 4 bitje
    ;biztosan nulla es A also 4 bitjere pedig nincs szukseg

    swap a ;temp[lo] felso negy bit
    anl a,#0Fh ;lesz az eredmeny also 4 bitje
    mov atlag,a

    mov a,b ;temp[hi] also negy bit
    swap a ;lesz az eredmeny felso 4 bitje
    orl atlag,a
    ret

    A 16-al való osztást elmagyarázom, ha nem értenéd. Itt arról van szó, hogy 16*255 nem lehet nagyobb mint 0FF0h. Tehát a felső bájt felső négy bitje mindig nulla lesz, ezt ki is használom a programban az ORL utasításban, nem kell ugyanis kimaszkolni. Az alsó bájt alsó négy bitjére nincs szükség, azt törlöm az ANL utasítással. A SWAP utasítás megcseréli az alsó és a felső négy bitet. Mivel az összeg alsó és felső bájtjából is csak 4-4 bitre van szükség, így ez kiváló megoldás a shiftelés helyett.

    A második feladatodat nem értem. Ha leírod pontosan a feladatot, akkor szívesen segítek.

    Köszi!

    A 2. feladatban az a lényeg, hogy 8 eszközt kell pwm vezérelni (0-127 a lehetséges értékek), miközben a mikrovezérlőknek legfeljebb 6 vezérlésére van lehetőségük, de mégis egy vezérlővel kellene 8 eszközt működtetni. A bemenet pedig egy 8*8 bites számsor.

    Itt igazából az a gond, hogy nem tudjuk, mit kellene csinálni.

  • zka67
    őstag

    Kérnék egy kis segítséget. Az alábbi kódrészlet egy 8 bites, i8051 mikrovezérlőre írt kód, ami 16 darab számot átlagol. Nagy vonalakban annyit csinál, hogy 16 értéket összeadja, majd eltolja 4-el balra, mert ez felel meg a 16-al való osztásnak. Ezt sajnos nem sikerül megértenem, hogy miért.

    változók:
    DSEG

    ORG 22H
    CIKLUS_SZAM: DS 01H
    BCD_DIGIT_SZAM: DS 01H
    RESULT_H: DS 01H
    RESULT_L: DS 01H


    ORG 30H
    ADAT_BUFF: DS 16
    OSSZEG: DS 02
    UJ_ERTEK: DS 08

    átlagoló:

    ATLAGOLAS:
    CLEAR_MEM #OSSZEG,#02
    MOV R0, #ADAT_BUFF
    MOV R1, #OSSZEG + 01
    MOV R2, #10H

    ATL_A:
    CLR C
    MOV A,@R0
    ADDC A,@R1 ;alsó byte
    MOV @R1,A
    DEC R1
    MOV A,@R1
    ADDC A,#0 ;felső bit + túlcsordulás + 0
    MOV @R1,A
    INC R1
    INC R0
    DJNZ R2,ATL_A

    ;---------------------
    MOV R2,#04
    ATL_B:
    MOV R0,#OSSZEG
    CLR C
    MOV A,@R0
    RRC A
    MOV @R0,A
    INC R0
    MOV A,@R0
    RRC A
    MOV @R0,A
    DJNZ R2,ATL_B
    RET

    Ezt leszimuláltuk, működik. Viszont egy kis magyarázat jól jönne.

    Valamint kaptunk egy feladatot, amiben egy 8*8 (7) bites bemenő érték állít be 8 kimenetet adott értékre 0-127 között. Vagyis 1 bitsorozat -> 8 eltérő kimenet.

    Itt valami olyasmit kellene csinálnom, ami szétszedi a bemenő bitsorozatot 8 bites mezőkre, és egy kimeneti változót ennek megfelelően állít be, vagy másolja át az értékeket. Jól gondolkodok?

    Az átlagolásod lényegesen egyszerűbben és gyorsabban is megoldható. Ez a szép az assembly nyelvben, hogy többféleképpen is meg lehet írni ugyanazt a programot, csak meg kell tornáztatni az agyat egy kicsit.

    dseg

    org $0030

    adat_buff: ds 16
    atlag: ds 2

    cseg


    ;------------------------------------------------------------------------------
    ; atlagolas - adat_buff atlagolasa.
    ;
    ; input: adat_buff, 16 db 8 bites adattal
    ; output: atlag, a 16 db 8 bites szam atlaga
    ;
    ; felhasznalt regiszterek:
    ; B - temp osszeg felso byte
    ; A - temp osszeg also byte
    ; R0- buffer pointer
    ;------------------------------------------------------------------------------

    atlagolas: clr a ;temp[16] = 0
    mov b,a

    mov R0,#adat_buff ;buffer elejere all
    _1: add a,@R0 ;temp[lo] += adat
    jnc _2 ;tulcsordult?
    inc b ;ha igen, temp[hi] += 1
    _2: inc R0 ;kovetkezo adatra all
    cjne R0,#adat_buff+16,_1 ;mindet osszeadta?

    ;BA shiftelese jobbra 4 bittel (osztas 16-al)
    ;mivel 16 db 8 bites szamot ad ossze, ezert B felso 4 bitje
    ;biztosan nulla es A also 4 bitjere pedig nincs szukseg

    swap a ;temp[lo] felso negy bit
    anl a,#0Fh ;lesz az eredmeny also 4 bitje
    mov atlag,a

    mov a,b ;temp[hi] also negy bit
    swap a ;lesz az eredmeny felso 4 bitje
    orl atlag,a
    ret

    A 16-al való osztást elmagyarázom, ha nem értenéd. Itt arról van szó, hogy 16*255 nem lehet nagyobb mint 0FF0h. Tehát a felső bájt felső négy bitje mindig nulla lesz, ezt ki is használom a programban az ORL utasításban, nem kell ugyanis kimaszkolni. Az alsó bájt alsó négy bitjére nincs szükség, azt törlöm az ANL utasítással. A SWAP utasítás megcseréli az alsó és a felső négy bitet. Mivel az összeg alsó és felső bájtjából is csak 4-4 bitre van szükség, így ez kiváló megoldás a shiftelés helyett.

    A második feladatodat nem értem. Ha leírod pontosan a feladatot, akkor szívesen segítek.

  • CPT.Pirk
    Jómunkásember

    Kérnék egy kis segítséget. Az alábbi kódrészlet egy 8 bites, i8051 mikrovezérlőre írt kód, ami 16 darab számot átlagol. Nagy vonalakban annyit csinál, hogy 16 értéket összeadja, majd eltolja 4-el balra, mert ez felel meg a 16-al való osztásnak. Ezt sajnos nem sikerül megértenem, hogy miért.

    változók:
    DSEG

    ORG 22H
    CIKLUS_SZAM: DS 01H
    BCD_DIGIT_SZAM: DS 01H
    RESULT_H: DS 01H
    RESULT_L: DS 01H


    ORG 30H
    ADAT_BUFF: DS 16
    OSSZEG: DS 02
    UJ_ERTEK: DS 08

    átlagoló:

    ATLAGOLAS:
    CLEAR_MEM #OSSZEG,#02
    MOV R0, #ADAT_BUFF
    MOV R1, #OSSZEG + 01
    MOV R2, #10H

    ATL_A:
    CLR C
    MOV A,@R0
    ADDC A,@R1 ;alsó byte
    MOV @R1,A
    DEC R1
    MOV A,@R1
    ADDC A,#0 ;felső bit + túlcsordulás + 0
    MOV @R1,A
    INC R1
    INC R0
    DJNZ R2,ATL_A

    ;---------------------
    MOV R2,#04
    ATL_B:
    MOV R0,#OSSZEG
    CLR C
    MOV A,@R0
    RRC A
    MOV @R0,A
    INC R0
    MOV A,@R0
    RRC A
    MOV @R0,A
    DJNZ R2,ATL_B
    RET

    Ezt leszimuláltuk, működik. Viszont egy kis magyarázat jól jönne.

    Valamint kaptunk egy feladatot, amiben egy 8*8 (7) bites bemenő érték állít be 8 kimenetet adott értékre 0-127 között. Vagyis 1 bitsorozat -> 8 eltérő kimenet.

    Itt valami olyasmit kellene csinálnom, ami szétszedi a bemenő bitsorozatot 8 bites mezőkre, és egy kimeneti változót ennek megfelelően állít be, vagy másolja át az értékeket. Jól gondolkodok?

  • AlapVaj
    csendes tag

    Na jó, kezdek szomorú lenni, hogy nem értek hozzá. Átírtam, viszont valamiért nem ad helyes eredményt, olyat is nem anagrammának ír, ami nem az :( pl alma lama, holott ez anagramma kéne legyen. Nem látom hol a hiba :(

    A lényege, hogy a 2szóban lévő megegyezőket kinullázza, és utána megnézi, hogy egyezik e (tehát mind 0, az 1es azért van ott a szavak végén, hogy jelezze, hogy ne végtelen legye,
    szo1 db 0,0,0,0...0,0,0,1
    ; 1. vizsgálat:

    XOR AX,AX ; Kinullázzuk
    XOR BX,BX ; Kinullázzuk
    XOR SI,SI ; Kinullázzuk

    CIKLUS:

    MOV AH, [szo1 + BX] ;Betöltjök AH-be a szo1 0,1,2,3....39ik bytját
    MOV AL, [szo2 + SI] ;Betöltjök AL-be a szo2 0,1,2,3....39ik bytját

    CMP AH, 1 ; Mindig megnézzük utolsó lépés e ez. Utolsó betű e?
    JE CIKLUS2 ; Elugrunk a másik CIKLUSBA, végeztünk az első lépéssel.

    CMP AH,AL ; Összehasonlítjuk a tartalmat
    JE NULL ; Ha 0, tehát egyenlők
    JNE ROSSZ ; Ha különböznek

    ROSSZ: ; Ha nem egyezik a két betű
    CMP AL, 1
    JE HELYESBIT
    INC SI ; Növeljük a regisztert
    JMP CIKLUS ; Ugrunk a következő karakterre

    HELYESBIT:
    XOR SI,SI ; 0-ra álítjuk, hogy előröl induljon
    INC BX ; Az első szó második lépésére
    JMP CIKLUS

    NULL:
    MOV szo1[BX], '0' ; Betesszük a szo1 BX-ben tárolt helyére a '0' értéket
    MOV szo2[SI], '0' ; Betesszük a szo2 CX-ben tárolt helyére a '0' értéket
    INC BX ; Novelunk
    INC SI ; Novelunk
    JMP CIKLUS

    ;2. vizsgálat:

    XOR AX,AX ; Kinullázzuk
    XOR BX,BX ; Kinullázzuk
    XOR SI,SI ; Kinullázzuk

    CIKLUS2:
    MOV AH, [szo2 + BX] ;Betöltjök AH-be a szo1 0,1,2,3....39ik bytját
    MOV AL, [szo1 + SI] ;Betöltjök AL-be a szo2 0,1,2,3....39ik bytját

    CMP AH, 1 ; Mindig megnézzük utolsó lépés e ez.
    JE DONTES ; Elugrunk a másik CIKLUSBA

    CMP AH,AL ; Összehasonlítjuk a tartalmat
    JE NULL2 ; Ha 0, tehát egyenlők
    JNE ROSSZ2 ; Ha különböznek

    ROSSZ2: ; Ha nem egyezik a két betű
    CMP AL, 1
    JE HELYESBIT2
    INC SI ; Növeljük a regisztert
    JMP CIKLUS2 ; Ugrunk a következő karakterre

    HELYESBIT2:
    XOR SI,SI ; 0-ra álítjuk, hogy előröl induljon
    INC BX ; Az első szó második lépésére
    JMP CIKLUS2

    NULL2:
    MOV szo2[BX], '0' ; Betesszük a szo1 BX-ben tárolt helyére a '0' értéket
    MOV szo1[SI], '0' ; Betesszük a szo2 CX-ben tárolt helyére a '0' értéket
    INC BX ; Novelunk
    INC SI ; Novelunk
    JMP CIKLUS2

    ;3. Lépés:

    DONTES:
    MOV SI, OFFSET szo1 ; Kialakított szó
    MOV DI, OFFSET szo2 ; Másik kialakított szó
    CMPSB
    JE ANAGRAIGEN
    JNE ANAGRANEM

    ;------------------------------------------------------
    ; Végső kiírások (eredmény):

    ANAGRANEM:

    CALL ujsor
    MOV SI, offset szoveg6 ; Nem Anagramma
    CALL kiiro

    RET ; Visszatérés az op. rendszerhez

    ANAGRAIGEN:

    CALL ujsor
    MOV SI, offset szoveg5 ; Anagramma
    CALL kiiro

    RET ; Visszatérés az op. rendszerhez

  • AlapVaj
    csendes tag

    Jó, hát az x86 architektúrában kevés a regiszter, de azért ami van azt használhatod ám :DD SI vagy DI megfelelő lehet az XX-ed helyére :K

    Az SI, és DI-t hogy tudom kitisztítani?
    XOR SI,SI?

  • Jester01
    veterán

    Végre megvan a tökéletes algoritmus! Nem 5 perc volt kitalálni (nem ismétléses permutációra). Viszont még mindig nagy a gond, mivel kéne helyesbítenem az "XX"-t :(
    Valakinek nincs ötlete? Most így látva a teljes lényegi, kódot könnyebb, gondolom.

    XOR CX,CX ; Kinullázzuk
    XOR AX,AX ; Kinullázzuk
    XOR BX,BX ; Kinullázzuk

    ; 1. vizsgálat:

    CIKLUS:

    MOV AH, [szo1 + BX] ;Betöltjök AH-be a szo1 0,1,2,3....39ik bytját
    MOV AL, [szo2 + XX] ;Betöltjök AL-be a szo2 0,1,2,3....39ik bytját
    CMP AH, 1 ; Mindig megnézzük utolsó lépés e ez.
    JE CIKLUS2 ; Elugrunk a másik CIKLUSBA

    CMP AH,AL ; Összehasonlítjuk a tartalmat
    JE NULL ; Ha 0, tehát egyenlők
    JNE ROSSZ ; Ha különböznek

    ROSSZ: ; Ha nem egyezik a két betű
    CMP AL, 1
    JE HELYESBIT
    INC XX ; Növeljük a regisztert
    JMP CIKLUS ; Ugrunk a következő karakterre

    HELYESBIT:
    XOR XX,XX ; 0-ra álítjuk, hogy előröl induljon
    INC BX ; Az első szó második lépésére
    JMP CIKLUS

    NULL:
    MOV szo1[BX], '0' ; Betesszük a szo1 BX-ben tárolt helyére a '0' értéket
    MOV szo2[DX], '0' ; Betesszük a szo2 CX-ben tárolt helyére a '0' értéket
    INC BX ; Novelunk
    INC XX ; Novelunk
    JMP CIKLUS

    ;2. vizsgálat:

    XOR CX, CX ; Kinullázzuk
    XOR AX,AX ; Kinullázzuk
    XOR BX,BX ; Kinullázzuk

    CIKLUS2:
    MOV AH, [szo2 + BX] ;Betöltjök AH-be a szo1 0,1,2,3....39ik bytját
    MOV AL, [szo1 + XX] ;Betöltjök AL-be a szo2 0,1,2,3....39ik bytját

    CMP AH, 1 ; Mindig megnézzük utolsó lépés e ez.
    JE DONTES: ; Elugrunk a másik CIKLUSBA

    CMP AH,AL ; Összehasonlítjuk a tartalmat
    JE NULL2 ; Ha 0, tehát egyenlők
    JNE ROSSZ2 ; Ha különböznek

    ROSSZ2: ; Ha nem egyezik a két betű
    CMP AL, 1
    JE HELYESBIT2
    INC XX ; Növeljük a regisztert
    JMP CIKLUS2 ; Ugrunk a következő karakterre

    HELYESBIT2:
    XOR XX,XX ; 0-ra álítjuk, hogy előröl induljon
    INC BX ; Az első szó második lépésére
    JMP CIKLUS2

    NULL2:
    MOV szo2[BX], '0' ; Betesszük a szo1 BX-ben tárolt helyére a '0' értéket
    MOV szo1[DX], '0' ; Betesszük a szo2 CX-ben tárolt helyére a '0' értéket
    INC BX ; Novelunk
    INC XX ; Novelunk
    JMP CIKLUS2

    Jó, hát az x86 architektúrában kevés a regiszter, de azért ami van azt használhatod ám :DD SI vagy DI megfelelő lehet az XX-ed helyére :K

Új hozzászólás Aktív témák

Hirdetés