[Asembler] Odbicie lustrzane tekstu


(uszaty_pl2) #1

Mam pewien problem ( nawet 2) z programem w asemblerze. Mam napisać program, który wyświetla odbicie lustrzane tekstu. Moje problemy to:

  1. Nie wiem dlaczego program nie dodaje na końcu '$'

  2. i nie wiem jak mam zliczać ilość znaków w tekscie.

Kod programu:

.MODEL TINY

.DATA

dl_zdania equ 11d; przypisz liczbe 11 dziesiętnie // EQU to dyrektywa asemblera, a w miejscu wartość wstawiasz liczbę. 

;Przy czym jako wartość można wstawić też nazwę rejestru (np. R5). Przy kompilacji asembler zastępuje wszędzie symbol wartością zadeklarowaną przez Ciebie.

;Raz zadeklarowanej wartości nie można zmienić.

TEXT db 'Jakis text!$'; tekst do odrocenia

TXET db ? ;tekst po odwroceniu

.CODE

Start:

mov cx, dl_zdania ; do rejestru liczka wstawiamy 11

mov bx, offset txet ;wskazujemy adres początku zmiennej txet

mov si, dl_zdania ;do rejestru indexowego wstawiamy 11

; loop1:

; cmp word ptr [di + text], 3h

; mov si, di

; je loop2

; inc di

; jne loop1

loop2:

mov al, [si + text] ;kopiujemy do al to co jest w adresie si + text(zzmiena text jest zawsze adresem poczatku zmiennej text)

mov ah, 0h; dla pewnosci zerujemy ah

mov [bx], ax ;do adresu na który wskazuje bx pzrenosimy wartość ax

inc bx ; powiększamy bx o 1

cmp si, 0; sprawdzamy czy si = 0

sub si, 1; pomniejszamy si o 1

ja loop2; jeżeli si >= 0 to skacze do linijki 14

jz dodaj; jeżeli si = 0 to skacze DO linii 23

dodaj:

inc bx ; powiększamy bx o 1

mov al, '$' ;kopiujemy do al znak końca textu

mov ah,0h ; dla pewnosci zerujemy ah

mov [bx], ax ;do adresu na który wskazuje bx pzrenosimy wartość ax

Koniec:

mov ah,4ch ; zatrzymanie procy

int 21h ;wywołanie systemu DOS

.Stack 100h ; ustawianie stosu

end start

end

([alex]) #2

Zliczanie najprościej się robi przez scasb;

Zmienna TXET ma rozmiar 1 bajt a ty próbujesz w niego wepchnąć 12 bajtów

Zapisujesz po dwa bajty mov [bx],ax nie wiem po kiego, przecież masz wpisać tylko jeden znak.

Nie wiem po kiego robisz cmp, skoro po nim robisz sub który psuje ci flagi, więc JA reaguje na flagi z sub.

Nie wiem po kiego jest jz dodaj, skoro kolejna instrukcja to właśnie to dodaj, jz dodaj oraz :dodaj nie potrzebne.

Odbicie najprościej robić na samym tekście:

  1. szukasz w tekście znaku '$', np przez SI

  2. cofasz się o jeden

  3. ustawiasz drugi rejestr na początek np DI

  4. dopóki di


(uszaty_pl2) #3

Wymyśliłem coś takiego:

.MODEL TINY

.DATA

TEXT db 'Jakis text!$'; tekst do odrocenia

.CODE

Start:

mov bx, OFFSET text 

  xor cx, cx 

  mov dx, '$'

  push BYTE PTR dx

Petla1: 

mov dx, [bx]

  cmp dx, '$' 

  je Dalej 

  push BYTE PTR dx

  inc bx

  inc cx 

  jmp Petla1 

Dalej: 

  mov ah, 02h 

Petla2: 

  pop dx 

  int 21h 

  loop Petla2 

Koniec:

mov ah,4ch ; zatrzymanie procy

int 21h ;wywołanie systemu DOS

.Stack 100h ; ustawianie stosu

end start

end

Tylko, że teraz wyświetla mi się: ChomikImage.aspx?k=1349251&t=634355640089914795&id=458101706


([alex]) #4

mov dl, [bx] // wczytuj znak nie słowo

cmp dl, '$' // porównujesz znak nie słowo

Kiedy ma niby druga pętla się skończyć? U ciebie działa dopóki nie wlezie na jakiś zabezpieczony obszar pamięci i windowsy nie wywalą program z pamięci.

Może jednak zrobisz tak jak zaproponowałem post wyżej?


(uszaty_pl2) #5

NIe chce, bo im bardziej skoplikowany kod tylko gorzej sie go zrozumieć na początku( to mój pierwszy program w asemblerze). Poza tym mam nie kumatego partnera w grupie, więc wole nie ryzykować.


([alex]) #6

To ty jesteś nie kumaty, ja proponuje najprostszy i najkrótszy wariant:

mov al,36

  mov di,OFFSET text

  mov si,di

  cld

  repne scasb

  dec di

odwrocenie:  

  cmp si,di

  jae Koniec

  mov al,[si]

  mov ah,[di]

  mov [si],ah

  mov [di],al

  inc si

  dec di

  jmp odwrocenie

Koniec:

(uszaty_pl2) #7

Dzięki wielkie.