Ciąg znaków TCC i ASM

0

Witam
chyba trochę zbyt długo nad tym siedzę albo czegoś nie rozumiem... dlaczego kod

char znak = 'A';
int main()
{
asm{
mov al,byte[znak]
mov ah,0x0e
int 10h
}
}

działa a ten poniżej już nie działa:

char znak[] = "A"
int main()
{
asm{
mov al,byte[znak]
mov ah,0x0e
int 10h
}
}

kompilator Turbo C Borlanda

0

Zdisassembluj obie wersje i wszystko będzie jasne.

0

szczerze to liczyłem na bardziej błyskotliwą odpowiedź.. skoro kod 2 nie działa to oznacza że linker źle zaadresował tę zmienną co potwierdza dekompilacja... pytanie dlaczego? czy ta zmienna powinna być inaczej zdefiniowana?

co gorsza ustawiając ds tak jak cs i si, na zmienną czyli tak:

char napis[]="a";

mov ax,cs
mov ds,ax
mov si,offset napis
lodsb
; w al nie ma znaku 'a' co chyba oznacza iż cs poleciał gdzieś...co jest dziwne ponieważ uruchamiam ten kod w taki sposób:

jmp 1000h:0000h

; i pod tym adresem jest cały kod ten kod powyżej.... 
0

Nie pytanie dlaczego tylko pokaż co kompilator wypluwa....
Skąd mamy wiedzieć co się kryje pod tym kodem?
Pokaż obie wersje tego programu najlepiej, i można dalej kombinować.

0

Właśnie pytanie "dlaczego" :) wydawało mi się na miejscu... otóż obie wersje kompilują się bez błędu...

kompiluję takim poleceniem:
tcc /c clearc.c
linker:
tlink /t /n /m clearc.obj ,out.bin

z tego wychodzi płaska binarka
kod programu jest banalnie prosty.. widać go w pierwszym poście.
ładuje go pod adres 1000h i potem skok do tego miejsca, kod się wykonuje jednak problem jest ze strony linkera który źle adresuje zmienną.... i nie wiem dlaczego?

coś takiego wypluwa disasm wersja nie działająca


0000 55             push    bp
0001 8BEC           mov     bp,sp
0003 83EC02         sub     sp,00002h
0006 A10800         mov     ax,[00008h]
0009 8946FE         mov     [bp-002h],ax
000C 8A46FE         mov     al,[bp-002h]
000F B40E           mov     ah,00Eh
0011 CD10           int     010h
0013 8BE5           mov     sp,bp
0015 5D             pop     bp
0016 C3             ret
0017 004100         add     [bx+di],al
001A

disasm wersja działająca:


0000 55             push    bp
0001 8BEC           mov     bp,sp
0003 83EC02         sub     sp,00002h
0006 C646FF41       mov     byte ptr [bp-001h],041h
000A 8A46FF         mov     al,[bp-001h]
000D B40E           mov     ah,00Eh
000F CD10           int     010h
0011 8BE5           mov     sp,bp
0013 5D             pop     bp
0014 C3             ret
0015
0
char znak = 'A';

znak jest charem A

char znak[] = "A"

znak jest wskaźnikiem na dwa znaki, A i \0

Z punktu widzenia asemblera, gdy taki znak wczytujesz do 8-bitowego rejestru, w pierwszym przypadku przypisujesz znak, a w drugim najmłodsze 8 bitów wskaźnika, czyli bzdurę.

0

@Azarien ma częściowo rację, tak powinno być. Aczkolwiek nie jest, do AL idzie bajt z 0x0008, dlaczego? Zerknij w dokumentacje linkera.

0

co jest dziwne ponieważ uruchamiam ten kod w taki sposób:
jmp 1000h:0000h

Dziwne jest to, że robisz dziwne rzeczy używając kompilatora sprzed ćwierćwiecza. Dlaczego nie czegoś współczesnego, np. NASM?

0

Dziwne jest to, że proszę o przepis na zupę a wy mi każecie czytać instrukcję kuchenki...

Piszę w realmode ,pewnien program nie ważne do czego... i męczy mnie smarowanie wszystkiego w ASM (fasm) i chcałbym nieco sobie przyśpieszyć pracę pisząc w C, a tu taki zonk...Proxima masz rację kod który mi generuje Turbo C jest bardzo szybki i faktycznie 16 bitowy, nie znalazłem lepszego kompilatora.. ale Open Watcom... muszę sprawdzić.

Azarien:
//char znak = 'A';
znak jest charem A
char znak[] = "A"
znak jest wskaźnikiem na dwa znaki, A i \0//

po części masz rację jednakże w obu przypadkach są to wskaźnik, znak nigdy nie będzie A bo w każdej chwili może być B, to po prostu adres do tej zmiennej i z char znak[] jest tak samo przy czym ten drugi wskazuje na ciąg znaków zakończonych właśnie \0.
dlatego właśnie w asmie wpisałem coś takiego

mov al,byte[znak] ; chciałem aby tutaj został pobrany pierwszy bajt spod tego adresu i przeniesiony do al
a nie coś takiego:
mov al,znak coś takiego nawet nie ma prawa działać...

Ma ktoś pomysł na to? chyba sam muszę rozwiązać ten problem... tak jak i poprzednie posty...

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