(Assembler NASM) Przerwanie 21h, funkcja 09h

0

Witam

Powoli uczę się Assemblera (NASM) i chcę użyć funkcji 09h przerwania 21h. Przeczytałem w spisie przerwań (link: http://www.ctyme.com/intr/rb-2562.htm) o tej funkcji i nie rozumiem o co chodzi w: "DS:DX -> '$'-term string". W polskim spisie jest napisane "DS:DX = wskaźnik do łańcucha zakończonego znakiem "$". Jak umieścić wskaźnik (offset) do DX (jeśli dobrze zrozumiałem)? Mógłby może ktoś umieścić przykład użycia 09h?

0

Pierwszy lepszy przykład:

org 100h

mov ah, 9
mov dx, asdf
int 21h

mov ax, 4c00h
int 21h

asdf db "WTF?!$"

Czyli normalnie wrzucasz do DX adres ciągu oraz numer funkcji do AH za pomocą instrukcji mov.

0

A czemu w opisie 21h funkcja 09h jest napisane DS:DX, a nie używa się wcale DS? Jak wpisać offset DX do DS? Ten kod nie działa:

section .data
tekst db "hellos ;D$"

section .text
mov ah, 9
mov dx, tekst
int 21h
 
mov ax, 4c00h
int 21h

PS. Kompiluje się poprawnie, ale przy próbie uruchomienia wyświetla się MessageBox w którym pisze:
Administrator: C:\Windows\system32\cmd.exe - hello The NTVDM CPU has encountered an illegal instruction CS:0000 IP:37a1 OP:ff d9 12 04 00 Choose "Close" to terminate th application.

0

Nie dziwota, że Twój kod nie działa, bo nie wskazałeś, pod jakim adresem ma znajdować się program po uruchomieniu oraz że to ma być program COM.

Czyli krótko mówiąc, dopisz na początku kodu org 100h.

0

Dodałem org 100h w section .text i przy kompilacji wywala error parser: instruction expected

0

Jak to kompilujesz, i co ważniejsze, jak linkujesz.

wartość rejestru ds trzeba ustawić na segment .data

0

Kompiluję komendą nasm -f elf hello.asm -o hello.exe, jak chcę użyć -f coff zamiast elf to jest jakiś błąd. Ale jak bym miał inne dane w segmencie .data, to muszę utworzyć osobny segment na to co ma się wyświetlić? W innym przykładowym "Hello World!" było przenoszenie zmiennej z tekstem na stos o jakiejś nazwie i chyba ten stos był przenoszony do ds.

@refresh

@Refresh

0
dane1	segment

txt1	db	"To jest przyklad", 10, 13, '$'
txt2	db	"I jeszcze ja!", 10, 13, '$'
dane1	ends
  
code1	segment
 
start:	
	mov	ax,seg txt1
	mov	ds,ax
	mov	dx,offset txt1
	mov	ah,9
	int	21h

	mov	dx,offset txt2
	mov	ah,9
	int	21h
 
	mov	ax,04c00h
	int	21h
code1	ends

end start
4

DOS ma dwa rodzaje plików wykonywalnych: .com i .exe.
Do tworzenia pierwszego wystarczy nam sam NASM, do drugiego potrzeba dodatkowo linkera.

-= program typu .com =-

COM jest łatwiejszy do napisania, ale nadaje się tylko do małych programów: których kod i dane mieszczą się w 64 kilobajtach (trochę mniej).
Cały program zajmuje jeden segment. Rejestry ds i es są automatycznie zainicjalizowane, więc nie trzeba się nimi przejmować.

Kod assemblerowy programu COM wygląda tak (składnia NASM):

[bits 16]
org 100h

	; push cs
	; pop ds

	mov dx,napis
	mov ah,9
	int 21h

	mov ax,4C00h
	int 21h

	napis db 'Ala ma kota',13,10,36

Linijka org 100h jest wymagana na początku każdego programu typu COM. Później mamy (niepotrzebne tak naprawdę) instrukcje push cs/pop ds, które działają tak jak mov ds,cs, choć taka dokładnie instrukcja nam się nie skompiluje. Ponieważ dane są w tym samym segmencie co kod, rejestr ds siłą rzeczy powinien mieć tę samą wartość co cs. Umieściłem te linie jednak w komentarzu, ponieważ mamy gwarancję że cs=ds=es na starcie programu.

W programie typu COM mamy też zapewniony stos, więc nie trzeba się nim przejmować.

Zamiast standardowego zakończenia programu mov ax,4C00h/int 21h można użyć formy skróconej: ret.

[bits 16]
org 100h

	mov dx,napis
	mov ah,9
	int 21h
	ret

napis db 'Ala ma kota',13,10,36

Na końcu napisu napisałem: 13,10,36. Pierwsze dwa bajty, w tej kolejności, to znak entera (przejścia do nowej linii), a 36 to kod ASCII znaku $. Mogłem napisać 13,10,'$', ale przyzwyczaiłem się do pisania 36.

c:\pp\myprogs\asm>nasm kom.asm -fbin -o kom.com

c:\pp\myprogs\asm>kom
Ala ma kota

-= program typu .exe =-

EXE to większy program, ma mniej ograniczeń. Można mieć wiele segmentów kodu i wiele segmentów danych. Standardowo mamy dostęp do 640 kB pamięci, ale istnieją tzw. DOS-extendery, które pozwalają na pisanie programów w trybie chronionym, także 32-bitowych, z dostępem nawet do całego RAM-u komputera i z obsluga swapa (zależnie od możliwości ograniczeń danego extendera).
Skupię się jednak na 16-bitowym programie w tybie rzeczywistym (real).

[bits 16]

segment code

..start:
	mov ax,data
	mov ds,ax

	mov dx,napis
	mov ah,9
	int 21h

	mov ax,4C00h
	int 21h


segment data
	napis db 'Ala ma kota',13,10,36

segment stack class=stack
	resb 4096

@Adam Boduch: dlaczego ten kod się nie chce pokolorować?

Program jest podzielony na trzy segmenty: kodu, danych i stosu. Nazwy segmentów są nieistotne, przyjęło się pisać: code, data, stack.

Ponieważ może być wiele segmentów kodu, system musi wiedzieć w którym miejscu zacząć wykonywanie kodu. W NASMie oznaczamy to etykietą ..start.

Segment stosu musi mieć class=stack, jeśli piszemy w NASMie. Poza zarezerwowaniem miejsca (tutaj 4 kB, choć starczyłoby znacznie mniej) nie trzeba nic z nim kombinować, rejestry ss i sp będą zainicjalizowane automatycznie.

Jednak nie będą zainicjalizowane automatycznie segmenty danych ds i es, a przynajmniej niekoniecznie na ten segment co trzeba. Dlatego tutaj napisałem mov ax,data/mov ds,ax (ponieważ nie da się zrobić bezpośrednio mov ds,data).
Może się okazać, że w tak małym programie bez inicjalizacji ds program będzie działał prawidłowo. Jednak nie przyzwyczajajmy się do tego – w programie typu EXE trzeba pamiętać o inicjalizacji ds.

Nie można również zastąpić wyjścia z programu instrukcją ret.

Taki plik .asm kompilujemy NASMem do formatu .obj. Plik .obj (albo wiele plików .obj) przekształcamy do .exe za pomocą linkera. Tego NASM nie potrafi, trzeba mieć osobny program. Ja posłużyłem się wlink, wchodzącym w skład pakietu Open Watcom, bo akurat go miałem na dysku:

c:\pp\myprogs\asm>nasm egze.asm -fobj

c:\pp\myprogs\asm>wlink file egze.obj
Open Watcom Linker Version 1.8
Portions Copyright (c) 1985-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
loading object files
creating a DOS executable

c:\pp\myprogs\asm>egze
Ala ma kota
0

Wielkie dzięki @Azarien ;). Idealnie wytłumaczone, zadziałało bez błędów. Bardzo się przyda mnie i na pewno innym co dopiero zaczynają.

0

@bajos poważnie polecam ci zaopatrzenie się w Emu8086, szczególnie jeśli uczysz się póki co 16 bitowego asma. To jest mega wygodne narzędzie :)

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