Здравствуйте! Обращаюсь к вам с просьбой помочь найти ошибку в переносе кода из C++ на Asm. У меня возникли проблемы с выделением памяти и дальнейшем ее использовании. Пример такой (удалил все лишнее, компилировал в TC 3.0, работает): Код (Text): #include "conio.h" #include "dos.h" typedef unsigned char byte; typedef unsigned int word; const word ScrSeg = 0xA000; byte gMode = 0x13; byte tMode = 0x3; int InitScr(word &VSS) { if (VSS == 0) { if (_dos_allocmem(4000, &VSS) != 0) return 1; else return 0; } else return -1; } void DoneScr(word &VSS) { if (VSS != 0) _dos_freemem(VSS); } void Flip(word D, word S) { asm { push ds mov ax, [D] mov es, ax mov ax, [S] mov ds, ax xor si, si xor di, di mov cx, 16000 db 0xF3, 0x66, 0xA5 pop ds } } void Clear(word Dest, byte Color) { asm { mov cx, 16000 mov es, [Dest] xor di, di mov al, [Color] mov ah, al mov dx, ax db 0x66, 0xC1, 0xE0, 0x10 mov ax, dx db 0xF3, 0x66, 0xAB } } void SetMode(byte Mode) { asm { xor ah, ah mov al, [Mode] int 0x10 } } // Example word VSS; void main() { SetMode(gMode); InitScr(VSS); Clear(VSS, 90); Flip(ScrSeg, VSS); while (!kbhit()); DoneScr(VSS); SetMode(tMode); return; } А перенос выглядит так (упростил почти до минимума, компилировал в TASM 5.0, соответственно не работает): Код (Text): model small stack 8h .const ScrSeg dw 0A000h gMode db 13h tMode db 3h .data VSS dw (0) .code StdExit proc far mov ax, 4C00h int 21h StdExit endp WaitAnyKey proc far mov ah, 8h int 21h ret WaitAnyKey endp main: ; ВЫДЕЛЕНИЕ ПАМЯТИ (InitScr) mov bx, 4000 mov ah, 48h int 21h ; <- вот тут все и накрывается jnc AllOk call StdExit AllOk: mov VSS, ax ; ПЕРЕКЛЮЧЕНИЕ НА ГРАФИКУ (SetMode) mov al, 13h xor ah, ah int 10h ; ЗАЛИВКА ЭКРАНА ЦВЕТОМ (Clear) mov cx, 16000 mov ax, VSS mov es, ax xor di, di mov al, 90 mov ah, al mov dx, ax db 66h, 0C1h, 0E0h, 10h ; mov shl eax,16 mov ax, dx db 0F3h, 66h, 0ABh ; rep stosd ; КОПИРОВАНИЕ ИЗ ПАМЯТИ В ЭКРАННЫЙ БУФЕР (Flip) push ds mov ax, ScrSeg mov es, ax mov ax, VSS mov ds, ax xor si, si xor di, di mov cx, 16000 db 0F3h, 66h, 0A5h ; rep movsd pop ds ; ОЖИДАНИЕ НАЖАТИЯ КЛАВИШИ (a la kbhit) call WaitAnyKey ; ПЕРЕКЛЮЧЕНИЕ В ТЕКСТОВЫЙ РЕЖИМ (SetMode) mov al, 3h xor ah, ah int 10h ; ОСВОБОЖДЕНИЕ ЗАНЯТОЙ ПАМЯТИ (DoneScr) mov ax, VSS mov es, ax mov ah, 49h int 21h ; КОРРЕКТНОЕ ЗАВЕРШЕНИЕ РАБОТЫ call StdExit end main Мне не столь вашет сам код, сколько то, что он не работает. При выделении памяти получаю (cf=1, ax=8, bx=7). Получается, что памяти не хватает и я могу использовать только 112 байт!? Но мне нужно почти 64Кб. Что же делать? Объясните ошибку или подкиньте идейку... P.S. Заливка (Clear) при замене VSS на ScrSeg также не хочет нормально работать: недобор 8 пикселей в самом конце. Но ПОЧЕМУ все работает в TC и BP (первоисточник я писал в нем давным давно)??? P.P.S. Я не отрицаю, что мой подход к работе с памятью может быть неправильным, но это единственное, что я нашел. Мне нужно использовать 64000 байт через адрес сегмента и ничего более. Нужно именно динамическое вфыделение памяти, и tmp dd dup (16000) не подойдет. Я откопал, что нужно сначала вернуть неиспользуемую память. Но мне это не сильно помогло...
Код (Text): main: mov ah, 62h int 21h mov es, bx mov bx, 1000h mov ah, 4Ah int 21h ; ВЫДЕЛЕНИЕ ПАМЯТИ (InitScr) mov bx, 4000 mov ah, 48h int 21h
Отвечаю сам себе: model small .data ; ... .code ResizeMem proc near mov ax, es mov bx, SEG end_seg_addr sub bx, ax mov ah, 04Ah int 21h jnc short resize_ok call StdExit resize_ok: ret ResizeMem endp main: mov ax, @data ; получение сегмента данных mov ds, ax call ResizeMem ; освобождение незанятой памяти ; выделение памяти call StdExit ; корректное завершение работы end_seg_addr SEGMENT ; это для выполнения ResizeMem end_seg_addr ENDS end main