[asm]asemblowanie + początki

0

Witam
Zaczynam uczyć się asemblera ...
Czy ktoś może mi napisać jaki jest najlepszy i jak się nim posługiwać. Zaczełem pisać własne programiki, ale nie umiem ich ort!. Na studiach mam laborki z asemblera i tam na razie działamy na AFD ucząć się działania systemu komputerowego. Ja chciałem ort! o krok dalej i zaczełem pisać coś swojego "użytkowego". Oczywiście chodzi mi o jakis ort! pod system windows xp...
Byłbym wdzięczny za szybką i konkretną odpowiedź.
Pozdrawiam

0

po pierwsze nie asemblerowanie a asemblowanie, a po drugie to fasm - świetny polski asembler:
http://flatassembler.net/ i http://decard.net/. Manual do fasma i przykłady wystarczą do nauczenia się składni a o samym asemblerze architektury x86\IA-32 to poczytaj w manualach intela:
http://www.intel.com/products/processor/manuals/index.htm

i ew. możesz zaglądnąć tu: http://www.rag.kgb.pl

0

jeśli chodzi o FASMa to się zgadzam - moim zdaniem najlepszy... Trochę podstawowych informacji znajdziesz na http://rudy.mif.pg.gda.pl/~bogdro/ . Jeśli chcesz programować pod Windows potrzebna ci będzie dokumentacja WinAPI

0

Nie no raczej chodziło mi o cos takiego co chodzi pod windowsem, ale ogólnie to jest dosowski - takie coś jak masm(ale niewiem jak sie tym posługiwać). Uczę się z książki Asembler dla procesorów intel - vademecum profecjonalisty i z tego co ja wiem to tam jest pod dosa.
Nie znam się ogólnie na asemblerze bo dopiero ort! się tego uczył - zaczynam poznawać z czego składa się procesor i podstawowe instrukcje w AFD. Jeśli ktoś by mógł by napisać jaki czy ten fasm też jest dobry do asemblera pod dosa to byłbym wdzięczny.

EDIT
Przy kompilowaniu takiego programu w fasm:

.model small
.stack 100h
.data
message db "Witaj swiecie!",0dh,0ah,'$'

.code
main proc
mov ax,@data
mov ds,ax

mov ah,9
mov dx,offset message
int 21h

mov ax,4C00h
int 21h
main endp

end main

Kompilator wywala mi błąd, że .modell small jest złe, a jak to usune to, że .stack 100h jest złe więc czego mam używać żeby to działało ? :-/
Sory, że jestem taki nerwowy, ale facet z laborek robi nam taką jazde, że chce się jak najszybciej zacząć ostro uczyć, ale bez ort! to ja nic nie zdziałam...

0
SI-Coder napisał(a)

Nie no raczej chodziło mi o cos takiego co chodzi pod windowsem

a fasm nie ma portu pod win? Chciałeś może asembler ze zintegrowanym edytorem? http://flatassembler.net/fasmw167.zip Gdybyś się nie połapał - 'fasmw.exe'.

SI-Coder napisał(a)

ale ogólnie to jest dosowski - takie coś jak masm

masm nie jest 'dosowski' /aktualnie nie jest ;P/ - to aplikacja konsolowa 32bit, ale pozwala na tworzenie plików MZ.

SI-Coder napisał(a)

Jeśli ktoś by mógł by napisać jaki czy ten fasm też jest dobry do asemblera pod dosa to byłbym wdzięczny.
jasne, że jest dobry... dowolnym portem fasm możesz wygenerować pliki binarne, MZ /dos/, PE /win/ PE64 /win64/, ELF /unix\lin/, ELF64 /chyba oczywiste/, i coś tam jeszcze... Btw. Fasm jako jedyny asembler nie potrzebuje linkera - sam 'wypluwa' binarki... oczywiście jest możliwość kompilacji do formatów COFF\M$ COFF. Byłbym wdzięczny gdybyś poczytał dokumentację dołączoną do fasma... Jak chcesz najpierw pisać pod dosa do ściągnij sobie paczkę fasma pod dosa - masz tak przykłady aplikacji typowo dosowych: http://flatassembler.net/fasm167.zip Oczywiście możesz programy dosowe pisać pod win w fasmw i kompilować oraz odpalać poprzez F9 :>

[EDIT:] // do powyższego edita

tamten program ma składnię masma, nie oczekuj, że jakikolwiek inny asembler /nie asemblator!/ to łyknie... pod fasmem będzie to wyglądać tak:

Format  MZ                      ; deklaracja formatu pliku wynikowego - MZ /dos/
stack   100h                    ; rozmiar stosu
entry   kod:main                ; entry point /'poczatek' programu/

segment dane                    ; segment o nazwie 'dane'... wiadomo

message  db 'Witaj swiecie', 0x0d, 0x0a, '$'

segment kod                     ; j\w tylko 'kod' ;)

main:                           ; etykieta... chyba wiadomo co to
        mov     ax, dane        
        mov     ds, ax

        mov     ah, 9
        mov     dx, message     ; pod fasmem nie potrzeba slowa 'offset'
        int     21h
        mov     ax, 4c00h
        int     21h 

ew. można wywalić początkową dyrektywę 'entry' - można ją dać zamiast etykiety 'main'... czyli tak:

entry kod:$                      ; czyli segment kodu : aktualna pozycja
        mov     ax, dane 
...
p.s. nawet najnowszy masm ma troche bugów - np. dołączanie bibliotek z poziomu kodu działa dosyć ciekawie /czasem gdzieś te informacje giną/. Do tego dochodzi jeszcze błąd w obliczaniu wyrażeń, o którym pisał swego czasu bart /TAC#8 - http://woodmann.com/bart/download.php?id=tac08h.zip/ - dodasz gdzieś nopa czy cokolwiek a w całkiem innym miejscu kodu masm może źle coś obliczyć :/ w sumie to z czymś takim spotkałem się może raz, ale pod masmem pisałem z konieczności tylko kilka razy. p.s. 2: w sumie większość czasu piszę pod win ale nie korzystam ze zintegrowanego edytora - vim rządzi :> p.s. 3: coś czuję, że mnie M. opitoli za rzucenie n oczywistych linków... i za pisanie chyba 10 raz tego samego /asm rulez, fasm rulez i te sprawy ;P/
0

Aha dzięki teraz już kumam ...
Mam do Ciebie ostatnią prośbe bo widze, że znasz się na sprawie. Miałem do zrobienia kilka programów i został mi jeden do zrobienia, którego męcze od 3h i nie potrafie zrobić.
Czy mógłbyś mi podsunąć przynajmniej pomysł jak zrobić taki program (chodzi mi tylko o podpowiedź bez pisania całego kodu bo sam chce do tego dojść):
napisz program, który wyszukuje najwięjszą wartość 8 bitową bez znaku z z buforu(byle jakiego - załóżmy, że DS) adresowane za pomocą rejestrów:
DI- segment
SI- offset
...
Podana jest wartość CX - załóżmy, że jest to 0011h.
AL - wyjście.

Mam to wykonać w afd także składnia jest nieważna - moge używać pętli takich zwykłych, które zmniejszają cx i poleceń mov, add, sub, dec, inc, jni, xchg, shl, shr.
Byłbym wdzięczny za pomoc w rozwiązaniu tego problemu.
Pozdrawiam

0

raczej ciężko to opisać - najłatwiej zrobić to po ludzku ;) czyli bierzemy pierwszy z brzegu a potem następne i sprawdzamy czy kolejny element jest większy, jeżeli tak to zamieniamy... liczba 8bit bez znaku to /w uproszczeniu/ najbardziej naturalny format danych - zwykły bajt. Wiem, że miałem kodu nie pisać, ale tak dawno nic pod dosa nie pisałem :> przykładowy program - właściwy algorytm potraktowałem wcięciem:

Format  MZ

segment kod

entry kod:$

        mov     cx, ilosc               ; inicjowanie wedle Twoich zalozen
        mov     di, extra
        mov     si, cos   
;------------------------------------------------------------------------------
; cx - liczba elementow, di - segment, si - offset
;------------------------------------------------------------------------------
                push    es              ; zachowujemy es - w tym programie nie
                xor     ax, ax          ; jest to konieczne, ale... ; ax = 0
                mov     es, di          ; ustawiamy segment
          _cmp_loop:
                mov     dl, [es:si]     ; w dl aktualna wartosc, w al aktualnie 
                cmp     al, dl          ; najwieksza
                jge     @f              
                mov     al, dl          ; najwieksza = aktualna
          @@:
                inc     si              ; ++pozycja
                loop    _cmp_loop       ; --licznik; jesli 0 - koniec
                pop     es              ; odtwarzamy es
;------------------------------------------------------------------------------
; cx = 0, si - offset konca koniec, ax /a raczej al/ - najwieksza liczba
;------------------------------------------------------------------------------
        mov     ax, 4c00h
        int     21h

segment extra

cos     db      22, 1, 53, 63, 23, 96, 6, 2, 123, 43, 4, 54, 35, 3, 87
ilosc   = $ - cos  

oczywiście można to rozwiązać nieco inaczej - np. zamiast:

        mov     dl, [es:si] 

można zastosować adresowanie względem rejestru bazowego z indeksowaniem /chyba tak to się nazywało - nie pamiętam ;P/ czyli:

        mov     dl, [es:bx+si-1]

ale w takim wypadku konieczne będzie zastosowanie zamiast loopa takiej konstrukcji:

        dec     si
        jnz     _cmp_loop 

ale przy takim rozwiązaniu zachodzi konieczność zmiany rejestrów - offset ląduje w bx a ilość elementów /licznik/ w si... co kto lubi... To co powyżej - działa, ale może być napisane minimalnie lepiej\zgrabniej ;)

p.s. stosowanie wcięć w asm to moim zdaniem zboczenie ;P
p.s. 2: 3h? ciężko mi w to uwierzyć...

0

Spróbowałem jednak napisać coś sam bo inaczej się nie naucze ...
Jeśli mógłbyś zobaczyć czy jest to dobry program to byłbym wdzięczny:

xor ax,ax
podmiana:
mov al,DI[SI]
inc SI
petla:
cmp al,DI[SI]
JC podmiana
inc SI
INZ petla
0

zrobiłeś parę błędów, instrukcji 'INZ' w x86 nie ma - zapewnie miałeś na myśli 'JNZ'... ale przejdźmy do rzeczy - pozwoliłem sobie skomentować Twój kod:

        xor ax, ax              ; zerowanie ax - dobrze ;)
podmiana:
        mov al, DI[SI]          ; po 1 : pod fasmem pisze sie [seg:reg]
                                ; po 2 : DI nie jest rejestrem segmentowym
        inc SI                  ; wskaznik = wskaznik + 1
petla:
        cmp al, DI[SI]          
        JC podmiana             ; to samo co 'JB' jesli 2 arg wiekszy to skok
        inc SI                  ; wskaznik = wskaznik + 1 
        INZ petla               ; na to nie mam pomyslu 'co to'... chyba mialo
                                ; jnz ale to nic nie da.  

to INZ to chyba miał być loop, ale nie sprawdzasz stanu rejestru CX przy podmianie - może to poskutkować 'przeoczeniem' końca bufora. Po

inc SI

powinno być dec cx
jz koniec

 a etykietę 'koniec' wiadomo gdzie dać... po moich drobnych poprawkach wygląda to tak:
```asm
        push    ds              ; zachowujemy ds - bedzie wygodniej odwolywac
        xor     ax, ax          ; sie do bufora /segment domyslny/ ; ax = 0
        mov     ds, di          ; ustawiamy segment ds - segment danych
podmiana:
        mov     al, [si]
        inc     si                      
        dec     cx              ; prawie to samo co loop - tylko w 2 strone ;)
        jz      _koniec
petla:
        cmp     al, [si]                
        jc      podmiana        ; to samo co 'JB' jesli 2 arg wiekszy to skok
        inc     si              ; wskaznik = wskaznik + 1 
        loop    petla           ; i powtarzamy... az cx = 0 
_koniec:
        pop     ds              ; odtwarzamy ds

Pobaw się nieco szykiem instrukcji - parowanie przy podmianie /mov nie modyfikuje flag/ :> Jeżeli wolno wam używać instrukcji łańcuchowych to część oznaczoną jako 'podmiana' można zapisać tak:

        dec     cx              ; klania sie parowanie instrukcji /jz/
        lods    byte [si]       ; mov al. [si] \ inc si
        jz      _koniec         ; lods nie modyfikuje flag

ew. 'lods byte [si]' można zapisać jako 'lodsb' - krótka forma :>

p.s. asm nie jest prostym językiem - wymaga odpowiedniego sposobu myślenia... ale głowa do góry, wyrobisz się ;)... ja siedzę w asemblerze od coś koło 5 lat i nie mogę powiedzieć abym opanował asma IA-32 idealnie - różne zawiłości instrukcji swoje robią /np. trzeba pamiętać, że inc\dec w przeciwieństwie do add\sub nie ustawiają flagi CF - przy testach na przekroczenia zera w którąś stronę trzeba opierać się na SF/.

0

Chciałem zrobić sobie sam sortowanie bąbelkowe buforu , ale niewiem czy dorze wykombinowałem. Jesli mógłbyś mi pomóc poprawić błędy w moim kodzie to byłbym wdzięczny.

xor ah,ah
push si
push cx

jzn petla
podmiana:
mov bl,[si+1]
mov bh,[si]
mov [si],bl
mov [si+1],bh
dec cx
inc si
inc ah
Jz _koniec
petla:
mov al,[si]
cmp al,[si+1]
jc zamiana
inc si
loop petla
_koniec:
cmp 0001h,al
pop cx
dec cx
pop SI
jc petla

Adres zawarty w DI, bufor - DS.
Pozdrawiam i prosze o wyrozumiałość :)
Jesli nie możesz połapac się w moim kodzie to jeśli możesz to napisz swoją wersję bubble sort.

0

Cóż, dzisiaj jestem trochę rozleniwiony więc napisałem własną implementację /a w sumie cały program - chciałem to pod SoftICE'm prześledzić ponieważ uważam, że nie jestem nieomylny ;P/:

Format MZ

segment dane

bufor   db 7, 64, 46, 71, 142, 42, 237, 1, 8, 48, 91, 56, 167, 29
ilosc   = $ - bufor

segment kod

entry kod:$

        push    dane
        pop     ds
        
        mov     cx, ilosc
        mov     bx, bufor
;------------------------------------------------------------------------------
_bs_loop: 
        mov     si, cx                  
        xor     di, di                  ; 'znacznik' zmian
  @@:
        dec     si
        jz      @f                      ; skok do nastepnego @@
        mov     ax, [bx+si-1]           ; wygodne rozwiazanie
        cmp     al, ah                  ; ax to w koncu ah << 8 + al
        jc      @b                      ; skok do poprzedniego @@
        xchg    al, ah                  ; zamiana elementow
        inc     di                      ; ilosc zmian++
        mov     [bx+si-1], ax
        jmp     @b                      ; skok do poprzedniego @@
  @@:
        test    di, di                  ; ZF = 1 jezeli di == 0
        jz      _end                    ; nie trzeba kolejnych iteracji
        loop    _bs_loop        
;------------------------------------------------------------------------------
_end:
        mov     ax, 0x4c00
        int     0x21

Gdzie jest algorytm - chyba widać ;) W sumie to po dodaniu 'znacznika zamiany' nie jest chyba zwykłe sortowanie bąbelkowe tylko przez wstrząśnięcie... ot, podrasowany 'bubel' ;P Jak widać na załączonym obrazku bufor przeniosłem do ds:bx aby zastosować adresowanie z indeksowaniem... tak dla zabawy :> Rejestr indeksowy robi dodatkowo za licznik. A poważnie to dobrym pomysłem na starszych procesorach jest zastosowanie 2 8bitowych części rejestru 16bit - zamiast 2 odwołań do pamięci przy zapisie\odczycie mamy jedno /na nowszych wpływa to negatywnie na wydajność - dostęp do wyższej części wymaga dodatkowych operacji/. Mam nadzieję, że nigdzie się nie machnąłem - pod debuggerem niby wszystko wygląda dobrze.

//dodane:
algorytm można nieco zmienić stosując parowanie instrukcji /np. przy pracy potokowej można odrobinę zniwelować negatywny wpływ skoków warunkowych/ i instrukcję 'loopnz':

;...
        xor     di, di                  ; 'znacznik' zmian
  @@:
        dec     si
        mov     ax, [bx+si-1]           ; w RM nie grozi GPF ;P
        jz      @f
        cmp     al, ah
        xchg    al, ah                  ; nie zmienia flag
        jc      @b
; reszta bez zmian...
        test    di, di                  ; ZF = 1 jezeli di == 0
        loopnz  _bs_loop

hmm... chyba odrobinkę przesadziłem [rotfl]
p.s. jak tak na to patrzę to myślę, że mógłbym zgarnąć parę złotych pisząc w asm dla inszych studentów [diabel]
@developerzy - przydałoby się poprawić kolorowanie składni dla asm - błędy: kolorowanie 'ch' w 'xchg' czy brak kolorowania liczb zapisanych jako 0x lub si przy indeksowaniu... A i jeszcze jedno - Coyote koloruje też liczby wchodzące w skład etykiet :/

1 użytkowników online, w tym zalogowanych: 0, gości: 1