Assembler - Operacje blokowe

Odpowiedz Nowy wątek
2018-01-04 17:31

Rejestracja: 2 lata temu

Ostatnio: 2 lata temu

0

Witam,
Mam problem z wykorzystaniem movsw, do skopiowania całej linii do bufora( w pętli).
Przybliżę problem, program ma zasłaniać losową linię znakami, a później ją przywrócić. Pracuję na dosboxie z włączonym trybem graficznym (vga) 0b800h.
Więc żeby nie zapomnieć co było w danej linii to chciałbym ją skopiować w pętli za pomocą operacji blokowej movsw (o ile wiem działa na SI i DI) do utworzonego Bufora w segmencie danych (db 160 dup(?) ), bo linia ma 80 słów co się przekłada na 160 bajtów, a następnie z tego bufora ją "odzyskać".
Czy mógłby ktoś podpowiedzieć jak się do tego zabrać ?

Z góry dziękuję za pomoc :)

Pozostało 580 znaków

Coredump
2018-01-04 22:29
Coredump
0
ECHU napisał(a):

Witam,
Mam problem z wykorzystaniem movsw, do skopiowania całej linii do bufora( w pętli).
Przybliżę problem, program ma zasłaniać losową linię znakami, a później ją przywrócić. Pracuję na dosboxie z włączonym trybem graficznym (vga) 0b800h.
Więc żeby nie zapomnieć co było w danej linii to chciałbym ją skopiować w pętli za pomocą operacji blokowej movsw (o ile wiem działa na SI i DI) do utworzonego Bufora w segmencie danych (db 160 dup(?) ), bo linia ma 80 słów co się przekłada na 160 bajtów, a następnie z tego bufora ją "odzyskać".
Czy mógłby ktoś podpowiedzieć jak się do tego zabrać ?

A jaki masz konkretnie problem? Dawno nie tykałem asemblera, więc to co tu wpiszę może nawet się nie kompilować. Movs kopiuje CX elementów z DS:SI do ES:DI. Na starcie DS wskazuje Ci na segment danych, a musisz nim wskazać na segment pamięci obrazu - w tzw. trybie tekstowym będzie to . Więc dla zachowania stanu DS wykonaj "push ds", a po operacji "pop ds". Wydaje mi się, że powinno to być coś takiego:

mov ax, ds
mov es, ax
mov di, offset_zadeklarowanego_bufora
push ds
mov ax, 0b800h
mov ds, ax
mov si, 0
mov cx, 80
rep movsw
pop ds

Skopiowanie w drugą stronę jest prostsze (zakładając, że w DS jest segment danych):
mov ax, 0b8000h
mov es, ax
mov di, 0
mov si, offset_zadeklarowanego_bufora
mov cx, 80
repo movsw

Pozostało 580 znaków

2018-01-04 22:35

Rejestracja: 16 lat temu

Ostatnio: 3 minuty temu

0

Dodałbym cld przed jednym i drugim movsw, choćby dla nawyku, bo jeśli w programie gdziekolwiek indziej pojawi się std to będzie bieda.

Pozostało 580 znaków

2018-01-05 10:26

Rejestracja: 2 lata temu

Ostatnio: 2 lata temu

0

Progr segment

assume cs:Progr,ds:dane,es:ekran,ss:stosik

start:

    mov ax,seg dane ;ładuj rejestry segmentowe DS i ES
    mov ds,ax
    mov ax,seg ekran ;pamięć ekranu do ES
    mov es,ax
    ;mov    ax,seg code
    mov ax,stosik
    mov ss,ax
    mov sp,offset stosik

    ;MOV    AH,0 ;wybór trybu pracy monitora
    ;MOV    AL,3 ;text 80x25 kolor
    ;INT    10H ;obsługa ekranu 
    ; Ukryj migotający kursor
    ;mov ah, 1
    ;mov ch, 2bh
    ;mov cl, 0bh
    ;int 10h
    ; Czeka na naciśnięcie dowolnego klawisza
    ;mov ah, 00h
    ;int 16h

    ;mov    ek[2000],219d ; Znak ASCII blok zamalowany 
    ;mov atr[2000],12d ; czerwony

    mov cx,80
    mov si,0
    jmp skopiuj
t1: 
    mov cx,80
    mov si,0

petla:
mov ek[si],219d
mov atr[si],12d
add si,2
loop petla

    jmp przywroc
    jmp koniec
ta: int 21h

przywroc:
;mov ax,0B800h
;mov es,ax
cld
mov si,offset Bufor
mov di,0
mov cx,80
rep movsw
;petla_p:;cmp si,0
;jz start
;jz koniec
;movsw
;LODSW
;mov ax,di
;mov bl,al
;mov bh,ah
;mov ek[si],bl
;mov atr[si],bh
;loop petla_p
jmp koniec

skopiuj:mov ax,0B800h
mov ds,ax
cld
mov di,offset Bufor
push ds
rep movsw
pop ds
mov ax, seg dane
mov ds,ax
jmp t1
koniec: Progr ends

dane segment

Bufor db 160 dup(?)

dane ends
stosik segment
stosik ends
ekran segment AT 0B800h
ek db ?
atr db ?
ekran ends

end start

Pozostało 580 znaków

2018-01-05 10:34

Rejestracja: 2 lata temu

Ostatnio: 2 lata temu

0

Przy takim zapisie dosbox się wywala, albo pokazuje w "przysłoniętej linii" różnokolorowe randomowe znaki, moim zdaniem problem jest w "segmencie" przywróć, ponieważ niezbyt wiem jak przy pomocy movsw który ładuje mi do di rzeczy z bufora, wrzucić je do tablic z segmentu ekranu, gdy chce np di przypisać do ax i i odpowiednio al i ah do tablic wyskakuje błąd forward reference needs override, natomiast jak chce użyć pośrednio zmiennych to błąd żeby użyć rejestrów. Z góry przepraszam też za bałagan w kodzie, który powstaje w wyniku różnych prób rozwiązanie problemu

Pozostało 580 znaków

Coredump
2018-01-05 11:33
Coredump
0

Główny problem widzę we fragmencie z etykietą "petla:"
Przy indeksowaniu tablicy rejestrem SI, używany jest rejestr segmentowy DS, a w nim, w tym miejscu programu, masz swój segment danych, a nie ekranu - nadpisujesz sobie bufor, do którego wcześniej skopiowałeś linię ekranu.

Druga sprawa - chociaż z punktu widzenia programu niekrytyczna - skoro i tak w różnych miejscach programu wpisujesz od nowa segment do DS, to "push ds" i "pop ds" które proponowałem, są bezużyteczne.

Pozostało 580 znaków

2018-01-05 11:44

Rejestracja: 2 lata temu

Ostatnio: 2 lata temu

0

cld
mov si,offset Bufor
mov di,0
mov cx,80
rep movsw

Pozostało 580 znaków

2018-01-05 11:45

Rejestracja: 2 lata temu

Ostatnio: 2 lata temu

0

Mam jeszcze pytanie, czy ten fragment kodu przywróci mi z Bufora automatycznie 80 "słów" na vga (ekran) ?
Bo wydaję mi się że nie powinien

Pozostało 580 znaków

Coredump
2018-01-05 11:52
Coredump
0
ECHU napisał(a):

Mam jeszcze pytanie, czy ten fragment kodu przywróci mi z Bufora automatycznie 80 "słów" na vga (ekran) ?
Bo wydaję mi się że nie powinien

A mi wygląda na to, że powinien - pod warunkiem, że w tym momencie w ES jest segment ekranu.

Pozostało 580 znaków

2018-01-05 12:13

Rejestracja: 2 lata temu

Ostatnio: 2 lata temu

0

https://zapodaj.net/13d9c80c42dd6.jpg.html

Gdy zakomentuje jump przywroc jest czerwona linia na górze, natomiast gdy odkomentuje i teoretycznie powinna tam wrócić wcześniejsza zawartość, modyfikuję się parę znaków w drugiej linii i pierwszy z pierwszej co widać na obrazku. poza tym za każdym razem dosboxa muszę wyłączać "ręcznie" i odpalać na nowo

Pozostało 580 znaków

Coredump
2018-01-05 12:36
Coredump
0

Gdy zakomentuje jump przywroc jest czerwona linia na górze, natomiast gdy odkomentuje i teoretycznie powinna tam wrócić wcześniejsza zawartość, modyfikuję się parę znaków w drugiej linii i pierwszy z pierwszej co widać na obrazku.

Niestety nie potrafię dojrzeć co jest nie tak, a nie mam akurat gdzie skompilować/włączyć i sprawdzić.
To co bym na ten moment polecił, to spróbuj podmieniać operację "rep movsw" na "rep stosw" - w odróżnieniu od movsw, nie kopiuje ze źródłowego obszaru pamięci, a tylko zapisuje w docelowym wartość rejestru ax; ale identycznie korzysta z ES:DI i CX. Na początku możesz zmienić np. funkcję zapamiętującą linię, dzięki czemu do bufora nie będzie skopiowana zawartość ekranu, a jakaś stała wartość - i będziesz mógł sprawdzić, czy funkcja przywracająca to prawidłowo wkopiuje. I tym podobne próby...

poza tym za każdym razem dosboxa muszę wyłączać "ręcznie" i odpalać na nowo

Dos-a trzeba specjalnie poinformować o zakończeniu programu. Było to coś takiego:
mov al, 0
mov ah, 4ch
int 21h

Pozostało 580 znaków

Odpowiedz

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