Приветствую всех! Нужно заполнить два сегмента 7000 и 8000 нулями, предложите вариант покороче mov ax, 7000h ; сегментный адрес 7000H mov es, ax ; загрузим в ES mov cx, 8000h ; в регистр CX количество повторений xor ax, ax ; обнулим AX mov di, ax ; регистр DI указатель на строку, тоже обнулим rep stosw ; проставить нули до конца сегмента mov cx, 8000h ; сегментный адрес 8000H и количество повторений mov es, cx ; загрузим в ES rep stosw ; проставим нули до конца сегмента Спасибо за внимание!
Вообще-то данных можно было и побольше привести. Какая разрядность, можно ли пользоваться стеком, что известно о состоянии перед выполнением этого участка... Судя по контексту, код 16-битный, флаг направления DF сброшен. С использованием стека вариант на 19 байт: Код (Text): push 7000h pop es mov cx, 8000h push cx xor ax, ax xor di, di rep stosw pop cx mov es, cx rep stosw В нереальном режиме можно обнулять всё сразу, уложившись в 17 байт: Код (Text): push 7000h pop es mov ecx, 20000h xor edi, edi salc db 67h rep stosb Как вариант, подходящи
й для также для 16-битного защищённого режима с плоским es, можно убрать инициализацию es, заменить обнуление edi на mov edi, 70000h и, если неизвестно, что перед началом флаг CF сброшен, вернуть xor ax,ax вместо salc.
те же 19 байт, но непонятных ) Код (Text): mov cx, 8000h push cx push 7000h xor ax, ax ; @a1: shl cx, 1 pop es @a0: mov di, cx stosb ; mov [es:di], byte 0 loop @a0 jc @a1
Код (Text): mov cx, 8000h ;cx=8000 [sp]=<end> push cx ;cx=8000 [sp]=8000,<end> push 7000h ;cx=8000 [sp]=7000,8000,<end> xor ax, ax ;ax=0000 cx=8000 [sp]=7000,8000,<end> @a1: shl cx, 1 ;ax=0000 cx=0000 cf=1 [sp]=7000,8000,<end> pop es ;es=7000 ax=0000 cx=0000 cf=1 [sp]=8000,<end> @a0: mov di, cx ;es=7000 ax=0000 cx=0000 di=0000 cf=1 [sp]=8000,<end> stosb ;es=7000 ax=0000 cx=0000 di=0001 cf=1 [sp]=8000,<end> ; mov [es:di], byte 0 loop @a0 ;es=7000 ax=0000 cx=0000 di=0001 cf=1 [sp]=8000,<end> (no move) jc @a1 ;es=7000 ax=0000 cx=0000 di=0001 cf=1 [sp]=8000,<end> (move to @a1) ... @a1: shl cx, 1 ;es=7000 ax=0000 di=0001 cx=0000 cf=0 [sp]=8000,<end> pop es ;es=8000 ax=0000 di=0001 cx=0000 cf=0 [sp]=<end> @a0: mov di, cx ;es=8000 ax=0000 cx=0000 di=0000 cf=1 [sp]=<end> stosb ;es=8000 ax=0000 cx=0000 di=0001 cf=1 [sp]=<end> ; mov [es:di], byte 0 loop @a0 ;es=8000 ax=0000 cx=0000 di=0001 cf=1 [sp]=<end> (no move) jc @a1 ;es=8000 ax=0000 cx=0000 di=0001 cf=1 [sp]=<end> (no move) ;результат: обнулили 2 первых байта сегментов 7000h и 8000h
а нет простите. все в порядке, это rep не реагигует на 0, а loop сначала уменьшает, потом проверяет. все в порядке, но переходов больше, да и метод Код (Text): push 7000h pop es mov cx, 8000h push cx xor ax, ax xor di, di rep stosw pop cx mov es, cx rep stosw здесь 65536 записей, а в указанном 131072
Инициализацию di можно опустить, сэкономив два байта - всё равно он в цикле прокрутится по всему сегменту 15 байт: Код (Text): mov ax, 7000h a1: mov es, ax xor cx, cx @@: stosb loop @b add ah, 10h jnp a1 Как вариант, вместо двух последних команд можно использовать xor ah,0F0h / js a1.
пытаясь сделать по короче вы увеличиваете в 2 раза количество операций. серьезное замедление выполнения программы Код (Text): push 7000h pop es mov cx, 8000h mov ds, cx xor ax, ax @@: mov [di], ax stosw loop @b 16 байт
Этот код не будет работать, если di изначально был нечётным - mov [0xFFFF], ax в реальном режиме вызывает #GP.
странно. 80386 хавает нормально. Код (Text): org 100h mov di, 1 mov ax, 7000h mov es, ax mov cx, 8000h mov ds, ax xor ax, ax @@: mov [di], ax stosw loop @b ret и ни какого #GP как под td, так и без.
вот если взять отладчик, который переключается в vm86, то #GP. лично ща на реальной машине проверил. и даже проконтролировал сегменты. оба нулевые.
а вот на P4 вылазит #GP всегда. вот гады. так. ща будем откапывать экстишку. хотя не. до завтра отложим.
Ну, по скорости любой вариант с loop однозначно проигрывает rep stosw, хотя, кажется, на хоть сколько-нибудь современных компах все варианты достаточно быстры. Насчёт FFFF... Intel в третьем томе даже прямо об этом пишет: Может, BIOS забыла выйти из нереального режима или тихо прикалывается, самостоятельно обрабатывая int 0Dh? Проверить нетрудно - в первом случае mov ax,[10000h] должно прекрасно отрабатывать, во втором случае можно посадить свой обработчик на int 0Dh.
я это делал. он по оканчании выводит, то оба сегмента заполнены 0 и что int ни разу не был вызван, но если был активирован vm86 режим, то int вызывается, а сегменты не обнуляются.
Увлеклись! По моему мнению самый приемлемый код этот cld push 7000h pop es mov cx, 8000h push cx xor ax, ax xor di, di rep stosw pop cx mov es, cx rep stosw и нагляден и краток, ваше мнение?
0136 + опционально варьируем (если сегменты будут отличаться от 7000 и 8000, то не придется много чего менять)