Mam pytanie :
#include<conio.h>
main()
{
char napis[4]="XXX$";
clrscr();
asm {
mov dx,offset napis
mov ah,09h
int 021h
}
getche();
return 0;
}
dlaczego nie wyswietla mi XXX tylko jakies znaki i dopiero XXX?
W Borlandzie 3.11?
Dzieki z góry za odpowiedz.
#include<conio.h>
void main(){
char napis[4]="XXX$"; // może nawet lepiej: char* napis="XXX$";
clrscr();
asm {
//push ds // tylko, gdy sizeof(napis)==4
mov dx,word ptr [napis]
//mov ax,word ptr [napis+2]
//mov ds,ax
mov ah,9h
int 21h
//pop ds
xor ah,ah // getche()
int 16h
mov ax,4c00h // exit()/return
int 21h
}
}
Bo 'napis' jest wskaznikiem do 4-bajtowej tablicy charow w segmencie danych. Sama zmienna 'napis' to char*, ona też znajduje sie w tym segmencie. Ty zaś ładujesz jej adres, a nie z niej adres do ciagu znakow. Zamiast mov dx,... mov ax,... mov ds,... mozesz uzyc jednej instrukcji : lds dx,[napis] , ale rowniez tylko wtedy, gdy , gdy sizeof(*)==4 (odpowiednie modele pamieci)
Dzieki za odpowiedz i pozdrawiam- z tymi adresami podejrzewałem ale za głupi jeszcze jestem widocznie...
Flabra!
Napisałem ale nie działa, lecz po zmianie na to:
#include<conio.h>
main()
{
char* napis="XXXXXXXX$";
clrscr();
asm {
mov dx,napis
mov ah,9h
int 21h
}
getche();
return 0;
}
I wszysytko działa mógłbyś mi powiedziec po co te kombinacje z sizeof i to co jest w komentarzu.
Dzieki z góry
Troszke wczesniej namieszalem... Teraz jest wszystko ok. Nie zdawalem sobie sprawy, ze deklaracja char zmienna[]="" powoduje, ze 'zmienna' traktowana jest jak etykietka. W ogóle dziwnie jest z taka deklaracją, niby etykietka (label), a typu 'char[9] _ss *' (specjalna wersja krotkiego wskaznika) :/
[code]void main(){
char napis1[]="\r\nXXX\r\n$"; // w segmencie stosu (ss)
char * napis2 ="\r\nYYY\r\n$"; // w segmencie danych (ds)
char far* napis3 ="\r\nZZZ\r\n$"; // w segmencie danych (ds)
// dla modeli tiny/small/medium wskaznik do danych ma
// tylko 2 bajty - bliski wskaznik - to tylko przesuniecie (offset)
// dla compact/large/huge * do danych jest zawsze daleki,
// czyli ma 4 bajty (2 bajty segment i 2 bajty przesuniecie)
asm{
push ds // dla compact/large/huge (ds!=ss) - save register
push ss * mov ax,ss * compact/large/huge (ds!=ss)
pop ds * mov ds,ax * compact/large/huge (ds!=ss)
lea dx,[napis1] * zaladuj przesuniecie napisu do dx * label ?
mov ah,9h
int 21h
pop ds // dla compact/large/huge (ds!=ss)
// tu nie ma 4 bajtow w malych modelach :]
// zreszta nie potrzeba, bo jest mov zamiast lds
mov dx,word ptr [napis2] // laduje tylko offset, bo ds jest zaladowane
mov ah,9h
int 21h
// gdyby nie to far* to linijka z lds nie mialyby
// prawa istnienia w malych modelach (tiny/small/medium)
// napis2 wskazuje na segment danych, wiec nie potrzeba
// chronic wartosci ds (przez push/pop)
lds dx,[napis3] // laduje 4 bajty ze wskaznika do ds:dx
* mov dx,word ptr [napis2] * moze byc również jak wczesniej
mov ah,9h
int 21h
xor ah,ah
int 16h
// debug code:
mov ax,word ptr ss:[napis1] // daje w ax 0d0a... więc etykietka ?
}
}[/code]
options/compiler/code generation/model <- najechac f1 i poczytac
Najlepiej skompilować to dla kilku modeli uruchomic przez f7/f8 i popatrzec na rejestry (window/register), ktore segmentowe (cs/ds/es/ss), w jakich modelach się różnią