заполнение нулями двух сегментов

Тема в разделе "WASM.ASSEMBLER", создана пользователем 0136, 14 авг 2009.

  1. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    Приветствую всех!
    Нужно заполнить два сегмента 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 ; проставим нули до конца сегмента

    Спасибо за внимание!
     
  2. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Вообще-то данных можно было и побольше привести. Какая разрядность, можно ли пользоваться стеком, что известно о состоянии перед выполнением этого участка... Судя по контексту, код 16-битный, флаг направления DF сброшен. С использованием стека вариант на 19 байт:
    Код (Text):
    1.     push    7000h
    2.     pop es
    3.     mov cx, 8000h
    4.     push    cx
    5.     xor ax, ax
    6.     xor di, di
    7.     rep stosw
    8.     pop cx
    9.     mov es, cx
    10.     rep stosw
    В нереальном режиме можно обнулять всё сразу, уложившись в 17 байт:
    Код (Text):
    1.     push    7000h
    2.     pop es
    3.     mov ecx, 20000h
    4.     xor edi, edi
    5.     salc
    6.     db  67h
    7.     rep stosb
    Как вариант, подходящи
     
  3. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    й для также для 16-битного защищённого режима с плоским es, можно убрать инициализацию es, заменить обнуление edi на mov edi, 70000h и, если неизвестно, что перед началом флаг CF сброшен, вернуть xor ax,ax вместо salc.
     
  4. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    код для реал мода, твой вариант действительно покороче и точно так нагляден, спасибо!
     
  5. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    те же 19 байт, но непонятных )
    Код (Text):
    1.     mov cx, 8000h
    2.     push    cx
    3.     push    7000h
    4.     xor ax, ax  ;
    5. @a1:
    6.     shl cx, 1
    7.     pop es
    8. @a0:   
    9.     mov di, cx
    10.     stosb
    11. ;   mov [es:di], byte 0
    12.     loop    @a0
    13.  
    14.     jc  @a1
     
  6. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    Код (Text):
    1.     mov cx, 8000h  ;cx=8000 [sp]=<end>
    2.     push    cx                    ;cx=8000 [sp]=8000,<end>
    3.     push    7000h               ;cx=8000 [sp]=7000,8000,<end>
    4.     xor ax, ax         ;ax=0000 cx=8000 [sp]=7000,8000,<end>
    5. @a1:
    6.     shl cx, 1                  ;ax=0000 cx=0000 cf=1 [sp]=7000,8000,<end>
    7.     pop es                    ;es=7000 ax=0000 cx=0000 cf=1 [sp]=8000,<end>
    8. @a0:   
    9.     mov di, cx                ;es=7000 ax=0000 cx=0000 di=0000 cf=1 [sp]=8000,<end>
    10.     stosb                        ;es=7000 ax=0000 cx=0000 di=0001 cf=1 [sp]=8000,<end>
    11. ;   mov [es:di], byte 0
    12.     loop    @a0                 ;es=7000 ax=0000 cx=0000 di=0001 cf=1 [sp]=8000,<end> (no move)
    13.  
    14.     jc  @a1                 ;es=7000 ax=0000 cx=0000 di=0001 cf=1 [sp]=8000,<end> (move to @a1)
    15. ...
    16. @a1:
    17.     shl cx, 1                  ;es=7000 ax=0000 di=0001 cx=0000 cf=0 [sp]=8000,<end>
    18.     pop es                    ;es=8000 ax=0000 di=0001 cx=0000 cf=0 [sp]=<end>
    19. @a0:   
    20.     mov di, cx                ;es=8000 ax=0000 cx=0000 di=0000 cf=1 [sp]=<end>
    21.     stosb                        ;es=8000 ax=0000 cx=0000 di=0001 cf=1 [sp]=<end>
    22. ;   mov [es:di], byte 0
    23.     loop    @a0                 ;es=8000 ax=0000 cx=0000 di=0001 cf=1 [sp]=<end> (no move)
    24.  
    25.     jc  @a1                 ;es=8000 ax=0000 cx=0000 di=0001 cf=1 [sp]=<end> (no move)
    26. ;результат: обнулили 2 первых байта сегментов 7000h и 8000h
     
  7. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    а нет простите. все в порядке, это rep не реагигует на 0, а loop сначала уменьшает, потом проверяет. все в порядке, но переходов больше, да и метод
    Код (Text):
    1.     push    7000h
    2.     pop es
    3.     mov cx, 8000h
    4.     push    cx
    5.     xor ax, ax
    6.     xor di, di
    7.     rep stosw
    8.     pop cx
    9.     mov es, cx
    10.     rep stosw
    здесь 65536 записей, а в указанном 131072
     
  8. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Инициализацию di можно опустить, сэкономив два байта - всё равно он в цикле прокрутится по всему сегменту :)
    15 байт:
    Код (Text):
    1.     mov ax, 7000h
    2. a1:
    3.     mov es, ax
    4.     xor cx, cx
    5. @@:
    6.     stosb
    7.     loop    @b
    8.     add ah, 10h
    9.     jnp a1
    Как вариант, вместо двух последних команд можно использовать xor ah,0F0h / js a1.
     
  9. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    пытаясь сделать по короче вы увеличиваете в 2 раза количество операций. серьезное замедление выполнения программы
    Код (Text):
    1. push 7000h
    2. pop es
    3. mov cx, 8000h
    4. mov ds, cx
    5. xor ax, ax
    6. @@:
    7. mov [di], ax
    8. stosw
    9. loop @b
    16 байт
     
  10. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Этот код не будет работать, если di изначально был нечётным - mov [0xFFFF], ax в реальном режиме вызывает #GP.
     
  11. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    странно. 80386 хавает нормально.
    Код (Text):
    1. org 100h
    2. mov di, 1
    3. mov ax, 7000h
    4. mov es, ax
    5. mov cx, 8000h
    6. mov ds, ax
    7. xor ax, ax
    8. @@:
    9. mov [di], ax
    10. stosw
    11. loop @b
    12. ret
    и ни какого #GP как под td, так и без.
     
  12. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    но и этот код на нем выполняется очень долго. а ваш так еще дольше.
     
  13. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    вот если взять отладчик, который переключается в vm86, то #GP. лично ща на реальной машине проверил. и даже проконтролировал сегменты. оба нулевые.
     
  14. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    а вот на P4 вылазит #GP всегда. вот гады. так. ща будем откапывать экстишку. хотя не. до завтра отложим.
     
  15. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Ну, по скорости любой вариант с loop однозначно проигрывает rep stosw, хотя, кажется, на хоть сколько-нибудь современных компах все варианты достаточно быстры.
    Насчёт FFFF... Intel в третьем томе даже прямо об этом пишет:
    Может, BIOS забыла выйти из нереального режима или тихо прикалывается, самостоятельно обрабатывая int 0Dh? Проверить нетрудно - в первом случае mov ax,[10000h] должно прекрасно отрабатывать, во втором случае можно посадить свой обработчик на int 0Dh.
     
  16. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    я это делал. он по оканчании выводит, то оба сегмента заполнены 0 и что int ни разу не был вызван, но если был активирован vm86 режим, то int вызывается, а сегменты не обнуляются.
     
  17. 0136

    0136 New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2007
    Сообщения:
    112
    Увлеклись! По моему мнению самый приемлемый код этот

    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
    и нагляден и краток, ваше мнение?
     
  18. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    0136
    + опционально варьируем (если сегменты будут отличаться от 7000 и 8000, то не придется много чего менять)
     
  19. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Да, он достаточно краток, чтобы не быть уменьшаемым без потери наглядности :)