[asm]Zamienia mi pozycje bl i bh :(

Odpowiedz Nowy wątek
2007-01-01 00:50
Assesmaniac
0

Odczytuje z pamieci 2 bajty, mam yasm jako kompilator i jest ogolnie ok ale mam maly prblem a mianowicie:

Mam w pamieci pod adresem xxxx:0x022B slowo: 0x00, 0x01 i na logige powinno odczytac tak:

bl = 0x01
bh = 0x00

i tak odczytuje wczesniej na poczatku programu inne dane z pamieci i dziala jak nalezy

ale niestety zamiast tego mam odczytane tak:

bl = 0x00
bh = 0x01

czyli odwrotnie niz powinno :(

Tak odczytuje:

add ax, 0x002C
mov di, ax
mov bx, [di]
mov [blockout], bx

Moze cos przeoczylem? jakas dzika flaga albo cos?

Tu jest caly kod programu a raczej prawiec skonczonego bootloadera:

[bits 16]

;main boot      
start:          cli
                mov ax, 0x07C0
                mov ds, ax
                mov es, ax
                mov fs, ax
                mov gs, ax
                mov ax, 0x0000
                mov ss, ax
                mov sp, 0xFFFF
                sti
                mov ax,0x0003
                int 0x10 ;clear and set screen
                mov ax, 0x1112
                xor bl, bl
                int 0x10 ;8x8 fonts
                mov si, booting
                call message
                call discinfo
                mov ax, kerneldir
                mov [filename], ax
                mov ax, [longdir]
                mov [namelenght], ax
                mov ax, [rootdir]
                mov [blockin], ax
                call search ;searching first block of /kernel/
                mov ax, kernelfile
                mov [filename], ax
                mov ax, [longfile]
                mov [namelenght], ax
                mov ax, [blockout]

                ;pusha
                ;add ax, 20
                ;mov ah, 0x0E
                ;mov al, '.'
                ;int 0x10
                ;popa

                mov [blockin], ax
                call search ;searching second block of kernel.bin
                jmp loadit

;a20 start function
a20:            in al, 0x92
                test al, 0x02
                jnz a20end ;a20 is set
                or al, 0x02
                out 0x92, al

a20end:         ret

;disc information function
discinfo:       mov ax, 0x0001
                mov [block], ax
                call readit ;reading sector from floppy
                mov ax, [ds:0x022C]
                mov [rootdir], ax
                mov ax, [ds:0x0216]
                mov [tablestart], ax
                mov ax, [ds:0x0220]
                mov [datastart], ax
                ret

;variables for disc
rootdir         dw 0x0000
tablestart      dw 0x0000
datastart       dw 0x0000

;search function
search:         xor cx, cx

searchmain:     inc cx
                mov ax, [blockin]
                mov bx, [datastart]
                add ax, bx
                mov [block], ax
                call readit ;reading sector from floppy
                pusha
                mov cx, 0x0008
                mov ax, 0x0200

searchloop:     pusha
                cld
                mov di, ax
                mov si, [filename]
                mov cx, [namelenght]
                rep cmpsb
                je found ;found file on floppy
                popa
                add ax, 64
                loop searchloop
                jmp notfound

found:          popa
                add ax, 0x002C
                mov di, ax
                mov bx, [di] <<--- to smierdzi i nie dziala jak nalezy :(
                mov [blockout], bx

                pusha
                mov dh, bh
                mov dl, bl

                mov ah, 0x0E
                ;mov al, '.'

                mov al, bh
                add al, 20
                int 0x10
                mov al, bl
                add al, 20
                int 0x10
                ;mov al, dh
                ;add al, 20
                ;int 0x10
                popa
                                    ;pusha
                                    ;mov bx, 0x2000
                                    ;add ax, bx
                                    ;mov si, 0x0200
                                    ;call message
                                    ;popa

                popa
                ret

notfound:       popa
                cmp cx, 0x0800
                jae error
                mov dx, [blockin]
                mov [nextin], dx
                call nextblock
                mov dx, [nextout]
                cmp dx, 0xFFF0
                ja error
                mov bx, [nextin]
                cmp dx, bx
                je error
                mov dx, [nextout]
                mov [blockin], dx
                jmp searchmain

;variables for search
filename        dw 0x0000
namelenght      dw 0x0000
blockin         dw 0x0000
blockout        dw 0x0000

;nextblock function
nextblock:      pusha

                ;pusha
                ;mov ah, 0x0E
                ;mov al, '|'
                ;int 0x10
                ;popa

                xor dx, dx
                mov ax, [nextin]
                mov bx, 256
                div bx
                mov cx, [tablestart]
                add ax, cx
                mov [block], ax
                call readit
                mov cx, 0x0200
                mov ax, 2
                mov bx, dx
                mul bx              
                add ax, cx

                ;mov si, ax
                ;call message

                mov si, ax
                mov bx, [ds:si]
                mov [nextout], bx
                popa
                ret

;variables for nextblock
nextin          dw 0x0000
nextout         dw 0x0000

;readit function
readit:         pusha
                xor dx, dx
                mov ax, [block]
                mov bx, 36
                div bx
                mov [scierzka], al
                mov ax, dx
                xor dx, dx
                mov bx, 18
                div bx
                mov [glowica], al
                inc dl
                mov [sektor], dl
                mov ah, 0x02
                mov al, 0x01
                mov cl, [sektor]
                mov ch, [scierzka]
                mov dl, 0x00
                mov dh, [glowica]
                mov bx, 0x0200
                int 0x13
                jc error
                popa
                ret

;variables for read
block           dw 0x0000
scierzka        db 0x00
sektor          db 0x00
glowica         db 0x00

;loadit jumper
loadit:         mov ax, [blockout]
                mov [nextin], ax
                mov cx, 0x0500 ;max 640KB kernel size

loaditloop:     pusha
                mov ax, [nextin]
                mov bx, [datastart]
                add bx, ax
                mov [block], bx
                call readit
                pusha
                ;kopiujemy do pamieci tam hen hen przy pomocy a20 powyzej 1MB

                ;pusha
                ;mov ah, 0x0E
                ;mov al, '.'
                ;int 0x10
                ;popa

                popa
                call nextblock
                mov ax, [nextout]
                mov [nextin], ax
                cmp ax, 0xFFFE
                je jumpit
                cmp ax, 0xFFF0
                ja error
                popa
                loop loaditloop
                jmp error

jumpit:         popa

                jmp jumpit

                call a20
                ;skaczemy do jajka z ustawionymi odpowienio rejestrami

;error
error:          mov si, errormessage
                call message

for:            jmp for         

;message function
message:        cld
                mov ah, 0x0E

messagechar:    lodsb
                cmp al, 0x00
                jz messageend
                int 0x10
                jmp messagechar

messageend:     ret

;messages for bootloader
booting         db 'Booting', 0x00
kerneldir       db 'kernel', 0x00
longdir         dw 0x0007
kernelfile      db 'kernel.bin', 0x00
longfile        dw 0x000B
errormessage    db '.Error', 0x00

;times 510 - ($ - start) db 0
;db 0x55
;db 0xAA

Pozostało 580 znaków

2007-01-01 02:33
0

nie jestem obeznany w asmie jak ty ale z tego co wiem to ładując wartość z rejestru do pamięci trzeba odwrócić bajty, zdejmując z pamięci też dostajemy odwrócone bajty, czyli jak w pamięci jest 0x1234 i zdejmujemy do AX to w AX jest 0x3412.

Może głoszę herezje, może mówię o czymś o czym wiesz od dawna ale jednocześnie proszę o potwierdzenie mnie w tych działaniach - tego że komunikacja rejestr-pamięć odwraca bajty w słowach.

Pozostało 580 znaków

2007-01-01 02:51
0

zgadza się prgtw, architektura x86 jest little endian co oznacza, że najniższy bajt liczby jest zapisywany /w pamięci/ jako pierwszy, najwyższy zaś jako ostatni /kolejność odwrócona gdyby ktoś nie załapał ;P/. Swoją drobą który raz ja to tutaj powtarzam? W przeciągu tygodnia już ze 2 razy o tym wspominałem... chyba będzie trzeba napisać FAQ bo zaczyna mnie to już nudzić...

OMG, przykład różnic pomiędzy programistą a coderem:

                                mov ax, 0x0000

3 bajty, nie lepiej tak? /2 bajty/

                                xor ax, ax

OMFG WTF!?

                                xor dx, dx
                                mov ax, [nextin]
                                mov bx, 256
                                div bx
                                mov cx, [tablestart]
                                add ax, cx

do kurki siwej dzielenie przez potęgi 2 wykonuje się przesumięciami bitowymi w prawo... a tu jeszcze dzielenie przez 256/dla kretynów - 256 = 2^8 czyli 1 bajt/! Czy wy mnie, kurna, chcecie do grobu wpędzić!? i ten cx... po jakiego grzyba ładować dane do rejestru aby tylko raz je użyć?

                                movzx ax, byte [nextin+1]
                                add ax, [tablestart]

ew. jeśli nie chcesz odrobinę nowszych rozkazów to:

                                xor ax, ax
                                mov al, byte [nextin+1] 
                                add ax, [tablestart]

[edit] dodałem +1, przez ten temat sam już zapomniałem o little endian... dziwne, że nikt mnie jeszcze nie opitolił /chyba, że nikt nie czyta\nie rozumie tego co piszę/ ;P [/edit]

I w drugą stronę:

                                mov cx, 0x0200
                                mov ax, 2
                                mov bx, dx
                                mul bx                               
                                add ax, cx

Mnożenie akumulatora zawierającego 2 (!) przez liczbę. OMFG jeżeli wyjdzie TAC 0x0A to ten bootloader wyląduje w najgłupszych snippetach asm jak nic, już ja się o to postaram! Bx nie jest już potem odczytywany więc na logikę:

                                shl bx, 1
                                add bx, 0x0200 

Next cud:

                                mov ah, 0x02
                                mov al, 0x01

i podobny:

                                mov dh, bh
                                mov dl, bl

może jeszcze tak po jednym bicie inicjować? Ciekaw jestem jak to byś z eax zrobił ;P Kolejny przykład poprawnego myślenia:

                                mov ax, 0x0201
                                mov dx, bx

ciekawi mnie również inicjowanie rejestrów segmentowych fs i gs - przecież ich nie używasz :/ Momentami ten kod wygląda jak pociągnięty jakimś obfuscatorem, więcej 'cudownych' fragmentów nie mam siły przytaczać /w sumie pozostałe są podobne do już przedstawionych/.
Już pomijam stosowanie pusha(d) i popa(d) bo to bootloader i niby liczy się rozmiar /patrząc na ten kod mam co do tego wątpliwości/... Gdzie dyrektywa 'org' czy coś w tym stylu? bez tej dyrektywy asmeblery przyjmują, że początek kodu wynikowego znajdzie się pod adresem 0 a bootloader raczej ląduje gdzieś indziej. Niby można pisać bez orga ale co do powyższego kodu mam wątpliwości... /może o tej godzinie nie widzę ustawiania cs/

Dzięki za uwagę i polecam się na przyszłość :>

p.s. mam dziwne wrażenie, że to prowokacja


I nie udawaj, że rozumiesz.

Pozostało 580 znaków

2007-01-01 11:53
Assesmaniac
0

Kwiatkow jest duzo :P ale to dla tego ze do konca go nie napisalem i on jest raczej typu "jesli zadziala to jest ok" nie zajmowalem sie jeszcze optymalizacja tego kodu.

po prostu duzo razy zmienialem w kodzie i latwiej mi bylo zostawic takie cos typu dzielenie przez 256 bo nie wiedzialem do konca o ile bede dzielic itd, a tak w ogóle to wykozystuje reszte z tego dzielenia jak tez sam wynik, a tak mi wygodniej.

A co do org to nie musi byc bo wystarczylo ze ustawilem odpowienio rejestry i kompilator sam juz reszte zalatwia, bo po prostu wszystko dziala jak trzeba i nigdzie do adresu 0000:xxxx sie nie odwoluje xD

Tak w ogóle to dzieki za wytkniecie bledow z tymi rejstrami i przeanalizowanie kodu, ale jak juz mowilem to jest faza wstepna i nie zajmowalem sie optymalizacja a raczej sie modlilem zeby to w ogóle cos z dyskietki odczytalo xD

Pozostało 580 znaków

2007-01-01 12:40
Assesmaniac
0

A jak jest dokladniej z tym bo mam wrazenie ze jak czytam z pamieci nie zawartej w kodzie to tam tylko trzeba przestawiac ?

mov ax, [di] <------ przestawiaja sie

mov ax, [etykieta] <------ jest ok

mov [etykieta], ax <--------jest ok

czy tylko mi tak sie zdaje?

Pozostało 580 znaków

2007-01-01 14:46
0

Odwracanie kolejności zachodzi zawsze - niezależnie czy to Twoja pamięć, czy odczytujesz\zapisujesz z MMXa, SSE czy też rejestrów ogólnego przeznaczenia, jak pisałem - architektura little endian. Do tego trzeba się przyzwyczaić.


I nie udawaj, że rozumiesz.

Pozostało 580 znaków

2007-01-01 15:09
Assesmaniac
0

Czyli po prostu wychodzi na to ze po prostu jak zapisze do zmiennej a pozniej odczytam to 2 razy sie przestawia i jest tak jak powinno :d mam farta bo wszedzie mam podwojne przeniesienia :d

Pozostało 580 znaków

2007-01-01 18:39
0

odwracanie kolejności bajtów następuje tylko przy przenoszeniu czegoś z pamięci do rejestru lub odwrotnie (np: pop eax lub movq mm0, [etykieta]). przy przenoszeniu czegoś z rejestru do rejestru (np: mov edx, eax lub movd eax, mm0) lub z pamięci do pamięci (np: movsd lub push [etykieta]) zamiana kolejności bajtów nie następuje.

myślę, że kwiatki typu:

                                mov ah, 0x02
                                mov al, 0x01

wynikały własnie z niewiedzy na temat 'endianess' (atsd: jak to jest po polsku?).

atsd:
po cholerę intel wprowadzał little- endian? bez tego dużo rzeczy dałoby się zrobić dużo szybciej, prościej i czytelniej. (wrrrr)


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

2007-01-01 20:38
Assesmaniac
0

A ja sie zawsze dziwilem dlaczego mi nieraz program jajca wyrabia xD

Jak na moje to koles co to projektowal musial sie chyba niezle zalac :P

A jak ma sie sprawa z eax itp? jak dziada odwrocic na lewa strone ? bo ax latwo: xchg al, ah

Pozostało 580 znaków

2007-01-01 21:25
0

Nie rozumiesz do końca zagadnienia. Z punktu widzenia programisty nie istnieje żaden problem w tej kwestii. Z twojego kodu można od razu poznać iż nie prześledziłeś zbyt dużej ilości programów napisanych przez innych programistów, ale to akurat sam nie wiem czy dobrze czy źle. W każdym razie postaram sie przedstawić jak to wygląda.

Jest sobie fragment pamięci o adresie powiedzmy 0010h i są w nim takie dane:
adres - dane
:0010 - 33 5C 2A FF EB FE 01 00 21 5A 91 00 00 CD 21 00

Tak więc wartość 2A ma adres 0012, wartość FE jest w komórce pamięci o adresie 0015. Jak wiadomo dane zapisywane do pamięci umieszczane są tak iż najpierw są zapisywane najmłodsze bajty. I tak po prostu jest.(To że jesteśmy przyzwyczajeni na co dzień robić to odwrotnie nie znaczy że ten sposób jest zły lub gorszy)

Prześledź teraz ten kod:
mov di, 0x12
mov ax, [di]

w rejestrze ax otrzymasz wartość ax=FF2A zamienione bajty kolejnością, ale to tylko kwestia zapisu bo tutaj po prawej masz młodsze bajty a przy zapisie w pamięci młodsze bajty idą do mniejszych adresów. W przypadku zapisu z rejestru do pamięci jest analogiczna sytuacja. Ale z punktu programisty w tym przypadku jest ci wszystko jedno bo to co zapiszesz do pamięci to dokładnie to samo odczytasz.

Dany ciąg pamięci można zapisać za pomocą kodu assemblera inaczej:
:0010 - 33 5C 2A FF EB FE 01 00 21 5A 91 00 00 CD 21 00

1.
db 0x33,0x5C,0x2A,0xFF,0xEB,0xFE,0x01,0x00
db 0x21,0x5A,0x91,0x00,0x00,0xCD,0x21,0x00

2.
db 0x33,0x5C
dw 0xFF2A
dw 0xEBFE
db 0x01,0x00
db 0x21,0x5A,0x91,0x00,0x00,0xCD,0x21,0x00

Oba kody 1. i 2. po skompilowaniu dadzą ten sam ciąg bajtów i jeżeli umieścisz go w pamięci pod adresem 0010h to wczytując mov ax, [12h] zawsze wczytasz wartość FF2Ah.

następny kod:
mov ah, [12h]
mov al, [13h]
mov bx, [12h]

No i jak już zrozumiałeś to powinieneś wiedzieć, że w rejestrze ax będziesz miał tą samą wartość co w bx.

Tak więc odpowiedz na pytanie:

A jak ma sie sprawa z eax itp? jak dziada odwrocic na lewa strone ? bo ax latwo: xchg al, ah

jest już ci nie potrzebna. No chyba, że do jakiś innych celów.


Pozostało 580 znaków

2007-01-02 00:00
Assesmaniac
0

Bo jak chce odczytac wartosc z pamieci do eax i chce wykonywac na niej operacje matematyczne to by sie odwrocic ten rejestr no nie? Chyba ze sie myle.

Dzieki wszystkim za wytlumaczenie :)

A co do ilosci przeczytanch programow to ja raczej biore ksiazke z instrukcjami, manual lub opis do rzeczy co chce uzyskac np odczyt z dyskietki jak ona jest zrobiona (dziwnie tez sie odczytuje :P ale sie nauczylem i dokopalem jak :) ) i z tego wszystkiego probuje wyskrobac cos dzialajacego :d

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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