Kopiowanie zawartości rejestru ebx do dynamicznie zalakowanej pamięci w asemblerze.

0

Witam.

Ostatnio chciałem się pobawić dynamiczną alokacją pamięci w assemblerze i mam pewien problem któreg nie mogę rozwiązać i zbytnio zrozumieć. Wymyśliłem że pobawię się cpuidem w asm + dynamiczna alokacja pamięci w asm. I problem taki jak w temacie posta.

Oto kod:

.model small
.586

.data
    napis db "Dynamiczna alokacja pamieci: ",0ah,0dh,"$"
	.stack 100h
.code 
    .startup
    
	mov dx,offset napis
	mov ah,09h
	int 21h
	
	xor eax,eax 
        cpuid 
        
        mov ah,48h ;Przerwanie Ms-Dos int 21h , ah=48h czyli dynamiczna alokacja pamięci 
        mov bx,50
        int 21h

       mov es,ax  ;Gdzieś znalałem to w internecie żeby przypisać adres segmentu dynamicznie zdefiniowanej pamięci do es 

       push ds
       pop es
       lea di,es ;Tu wywala błąd w trakcie asemblacji "
       lea si,ebx ; Tu zapewne również wyrzuci błąd w trakcie assemblacji. 
       cld 
       rep movsb

	
	
	
    .exit
end

Jestem początkującym w assemblerze i męczę się z tym już parę tygodni i już mi ręcę opadają ale się nie poddaje i dlatego liczę na pomoc ludzi mających wiedzę w tym języku.
Jest to składnia Masma jak coś.
Jeśli to komuś się przyda post jest sposobem szukania rozwiązania tego problemu: Złączanie dwóch stringów w jeden w Assemblerze

Życzę miłego dnia i bardzo dziękuję za pomoc każdej osobie. Jeśli będzie czegoś brakować itp to proszę pisać.

2

mov es,ax ;Gdzieś znalałem to w internecie żeby przypisać adres segmentu dynamicznie zdefiniowanej pamięci do es

Uprawiasz magie? Bo robisz to bezkrytycznie niczym rzucenie zaklecia :)

Generalnie w assemblerze to mozesz pisac do rejestrow albo do adresow w pamieci. I Ty chcesz pisac do adresu a nie do rejestru.
W intelu to sie robi piszac [rejestr] albo (rejestr) w odpowiedniej intrukcji. Dokladnie Ci nie powiem bo ekspertem nie jestem i jeszcze jakas glupote palne. Musisz juz sam doszukac w dokumentacji/SO.

EDIT: to wazne a nie wspomnialem*- rejestr przechowuje adres pamieci! Czyli jest takim wskaznikiem.


https://www.cs.virginia.edu/~evans/cs216/guides/x86.html

mov [esi+eax], cl ; Move the contents of CL into the byte at address ESI+EAX

3
 mov es,ax  ;Gdzieś znalałem to w internecie żeby przypisać adres segmentu dynamicznie zdefiniowanej pamięci do es 

No spoko, załóżmy że to przerwanie ustawia adres zaalokowanej pamięci do ax ale ty za chwilę robisz:

push ds
pop es

czyli nic innego jak mov es, ds czyli nadpisujesz tą wartość tym co było w ds, jaki to ma sens? Po co te pushe i popy? o_O

Dalej używasz movsb które kopiuje z ds:si to es:di, więc co ty tam za cyrk robisz? Powinieneś ustawić si na offset bufora z którego kopiujesz mov si, offset napis a di ustawić na 0 bo chcesz kopiować od początku tego zaalokowanego bloku.

0

@Shalom:

Witam.

Po kliku godzinach walki z tym co pan napisał nie dało takich efektów jakich oczekiwałem.

  1. Dynamicznie alokuje pamięć za pomocą ah=48h int 21h czyli przerwanie Ms-Dos. Z tym mam taki problem że zwraca flagę CF czyli jest błąd. Wyczytałem że na Ms-Dos nie da się alokować dynamicznie pamięć ponieważ dos alokuje całą dostępną pamięć gdy jest uruchamiany program.
  2. Czy można prosić o jaśniejsze wytłumaczenie tego co pan napisał. Bo to rozumiem 5 przez 4.

Mi chodzi o to żeby tekst np: "Ala ma kota" skopiować do dynamicznie zdefiniowanej pamięci. Zostało mi polecone użycie movsb. Więc bym prosił o jasne i szczegółowe wyjaśnienie.

Bardzo dziękuję za każdą formę pomocy i życzę miłego dnia.

Używam Masma jak coś.

1
  1. No na to ci już nic nie poradzę skoro nie da się alokować :D :D Nie programuj pod dosa?
  2. Nie wiem co można jaśniej opisać. Wklejasz losowe instrukcje bez próby zrozumienia co one robią - tak się programować nie da. Poproszę od ciebie o opis do każdej linijki tego twojego kodu z wyjaśnieniem po co ta linijka jest i co robi.
0
  1. Znaczy ja nie wymagam że trzeba to rozwiązać tylko myślałem że może jest jakieś rozwiązanie tego
  2. Oto kod z wyjśnieniem:
.model small ;Pamięć w stylu jeden segment danych , jeden segment kodu
.386 ; wskazanie na obsługę rozkazów procesora 

.data ;Sekcja Danych 
     tekst db "CPUID (Test) ",0ah,0dh,"$"  ;zmienna tekst
	 wzor db "Tekst przykladowy",0ah,0dh,"$" ;zmienna wzor
	.stack 100h ;alokacja stosu procesora 
.code ;sekcja kodu 
    .startup ;Załadowanie rejestrów potrzebnych do działania programu. Robi to makro .startup
    
    mov dx,offset tekst 
    mov ah,09h    ; Wyświetlam napis
    int 21h
    
   mov ah,48h
   mov bx,1000h   ;Dynamicznie alokuje pamięć na rozmiar 64kb. Ustawia flagę CF czyli jest jakiś błąd
   int 21h
   
   mov es,ax  ;Ustawiam adres dynamicznie zalakowanego segmentu do es czyli dodatkoweg segmentu danych
   
   mov si,offset wzor
   mov di,es   ;kopiuje tekst z zmiennej do tej pamięci
   cld 
   rep movsb
   
   mov dx,es
   mov ah,09h   ; Wyświetlam napis w zalakowanej dynamicznie pamięci czyli powinno być "Tekst przykładowy"
   int 21h
	.exit ;Makro na koniec programu 
end

Jeżeli coś będzie jeszcze potrzebne to proszę pisać

2

mov di,es ;kopiuje tekst z zmiennej do tej pamięci

o_O Nie zgaduj tylko czytaj dokumentacje. mov di, es to jest nic innego jak przypisanie sobie di = es.
Czemu nie ma komentarza do rep movsb? To jest kluczowy element, którego zupełnie nie rozumiesz.
movsb kopiuje dane z ds:si do es:di. Widzisz problem? Ty ustawiłeś di = es więc jeśli np. ten twój zaalokowany segment pamięci ma adres 0xABCD to zamiast pisać do pamięci 0xABCD 0000 (czyli od początku tego segmentu) piszesz do 0xABCD ABCD! Co gorsza rep movsb to jest instrukcja która wykonuje to tyle razy ile masz w liczniku cx. Ile on wynosi u ciebie? Nie wiadomo bo nigdy go nie ustawiłeś...

Może warto zacząć od tego czy rozumiesz jak działa adresowanie którego próbujesz używać. Adres składa się z dwóch 16 bitowych kawałków - segmentu i offsetu. Dzięki temu możesz mieć 2^16 segmentów i 2^16 bajtów w każdym z nich.

1

Bardzo dziękuję każdemu za odpowiedź. Jestem początkujący w Assemblerze i poza czytaniem książek to takie uwagi oraz wytłumczanie powoduje że moja wiedza idzie w górę.
@Shalom Już rozumiem mój błąd. Teraz jak na to patrzę to popełniałem Bardzo głubi błąd :D. Dziękuję za chęć męczenia się w tłumaczeniu mi tego ale efekt jest pozytywny bo zrozumiałem to i wiem że programowanie to jest rzecz której będę się starał uczyć całe życie ponieważ mam chęć rozwijać swoją wiedzę oraz jest to moja pasja życiowa.

Jeszcze raz bardzo dziękuję za pomoc i życzę miłego dnia wszystkim.

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