На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Помните, что у нас есть FAQ раздела Assembler и Полезные ссылки. Посмотрите, возможно, там уже имеется решение вашего вопроса.

3. Настоятельно рекомендуем обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "Ассемблер" будут отправляться в Корзину для мусора.
  3.2. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).
  3.3. Нежелательно поднимать старые темы (не обновлявшиеся более года) без веской на то причины.

Не забывайте также про главные Правила форума!

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
  
> запись адреса в регистр CS , Как записать адрес в регистр сегмента кода - CS
    Когда программа загружается в память операционной системой (например DOS, но это не важно), то насколько я знаю (может я ошибаюсь?) сама операционная система записывает адрес сегмента кода в регистр CS и соответственно по этим адресам и загружает соответствующую программу. Вопрос, как записать адрес в регистр CS если я загружаю программу в память собственноручно написанным загрузчиком без какой бы то ни было операционной системы?

    Я так понял (может я опять ошибаюсь) инструкции вида:
    ExpandedWrap disabled
      PROG segment
      assume cs:PROG

    на самом деле ничего в CS не пишут.

    И ещё, вот такой код:
    ExpandedWrap disabled
      PROG segment
      assume cs:PROG, ds:PROG, ss:PROG, es:PROG

    говорит о том, что регистры cs, ds, ss, es будут иметь одинаковые адреса и стоит записать адрес только в один, а в остальных он появиться автоматически?

    Если ничего не записал в CS (я так пробовал и всё работало), то сам компилятор ассемблера - например MASM, пишет в CS ноль - хотя это бред скорее всего? Я программу загружал в начало памяти, а в CS ничего не писал и программа, повторяю без операционной системы, работала.

    Как быть если программа не вмещается в сегмент? Первый момент, как узнать что программа не вмещается в сегмент? Просто компильнуть код и посмотреть поместиться по размеру в 65536 байт (почему не 65535? 65535 + один первый нулевой байт) или нет?

    Далее, если мне в процессе работы надо прыгнуть на участок кода который находится в другом сегменте кода и он не в начале этого сегмента, при этом такие прыжки мне надо совершать неоднократно по ходу выполнения программы, причём в разные места другого сегмента кода. Как быть? Писать в какой то регистр разные числа, потом в самом начале кода программы который находится в другом сегменте, проверять эти числа и в зависимости какое число прыгать на соответствующий участок кода уже в этом сегменте, так как в регистр IP ничего записать напрямую я не могу? Если это так, то тогда не понятно как быть если программа была загружена операционной системой и выполняется вместе с ней. Откуда программа будет знать по каким адресам загрузили вторую часть её кода находящегося в другом сегменте, что бы этот адрес записать в CS? Когда я сам, гружу две части программы самописным загрузчиком, я знаю по каким адресам я её гружу, поэтому знаю, что записать в CS.

    Да и ещё, когда я поменял адрес в CS, в IP остаётся ведь прежний адрес, а мне надо выйти как то на начало этого сегмента (имеется ввиду вторая часть моей программы которая не влезла в первый сегмент кода), то есть записать в IP ноль, что бы сделать проверку чисел и в зависимости от этого сделать соответствующий прыжок. Как это сделать? Я так думаю, что делается как то совсем по другому, но как?

    У форумчан может возникнуть вопрос, зачем мне это надо? Просто хочу до тонкостей разобраться.

    За любую помощь: ссылки на русскоязычный материал, или просто за объяснение вопроса или какой либо его части, буду благодарен!

    Сам я перерыв интернет на эти вопросы ответа так и не нашёл, поэтому пришлось обратиться за помощью к форумчанам, (может плохо искал).
    Сообщение отредактировано: v4567 -
      Цитата v4567 @
      Вопрос как записать адрес в регистр CS?

      используй:
      ExpandedWrap disabled
        jmp segment:offset
        ;или
        call segment:offset
        а куда я тогда прыгну? Мне ведь надо попасть во второй сегмент моего кода и в нём прыгнуть.
          Цитата v4567 @
          Мне ведь надо попасть во второй сегмент моего кода и в нём прыгнуть.

          Используй FAR jump

          ExpandedWrap disabled
            EB cb   JMP rel8    Jump short, relative, displacement relative to next instruction.
            E9 cw   JMP rel16   Jump near, relative, displacement relative to next instruction.
            E9 cd   JMP rel32   Jump near, relative, displacement relative to next instruction.
            FF /4   JMP r/m16   Jump near, absolute indirect, address given in r/m16.
            FF /4   JMP r/m32   Jump near, absolute indirect, address given in r/m32.
            EA cd   JMP ptr16:16    Jump far, absolute, address given in operand.
            EA cp   JMP ptr16:32    Jump far, absolute, address given in operand.
            FF /5   JMP m16:16  Jump far, absolute indirect, address given in m16:16.
            FF /5   JMP m16:32  Jump far, absolute indirect, address given in m16:32.
            ExpandedWrap disabled
              .286                    ; разрешаем использование инструкций процессора 80286
               
              ;-- Сегменты кода --------------------------------------------------------------
              CODE        SEGMENT PARA 'CODE'
                      ASSUME  CS:CODE, DS:DATA, SS:STK
               
              Start:
                      mov ax,DATA
                      mov ds,ax
                      mov es,ax
               
                      call    MyProc1     ; near call (ip)
                      call    MyProc2     ; far call (cs:ip)
                      call    MyProc3     ; far call (cs:ip)
                      jmp Exit        ; far jump (cs:ip)
               
              MyProc1     PROC    NEAR
                      mov ah,2
                      mov dl,'1'
                      int 21h
                      ret         ; near ret
              MyProc1     ENDP
               
              CODE        ENDS
               
              ;---------------------------------------
               
              CODE2       SEGMENT PARA 'CODE'
                      ASSUME  CS:CODE2
               
              MyProc2     PROC    FAR
                      mov ah,2
                      mov dl,'2'
                      int 21h
                      ret         ; far ret
              MyProc2     ENDP
               
              MyProc3     PROC    FAR
                      mov ah,2
                      mov dl,'3'
                      int 21h
                      ret         ; far ret
              MyProc3     ENDP
               
              CODE2       ENDS
               
              ;---------------------------------------
               
              CODE3       SEGMENT PARA 'CODE'
                      ASSUME  CS:CODE3
               
              Exit    LABEL   FAR
                      mov ah,2
                      mov dl,'4'
                      int 21h
                      mov ax,4C00h
                      int 21h     ; выход из программы
               
              CODE3       ENDS
               
              ;-- Сегмент данных -------------------------------------------------------------
              DATA        SEGMENT PARA 'DATA'
              DATA        ENDS
               
              ;-- Сегмент стека --------------------------------------------------------------
              STK     SEGMENT PARA STACK 'STACK'
                      db  256 dup (?) ; размер стека (256 байт)
              STK     ENDS
               
              END     Start           ; определение точки старта


            Добавлено
            И ассемблер сам расставит нужные call и jmp со сменой CS.

            CS вообще по-разному можно сменить.
            Дальний jmp far:
            ExpandedWrap disabled
              db 0EAh
              dw Offset,Segment
            Дальний call far:
            ExpandedWrap disabled
              db 09Ah
              dw Offset,Segment
            Или так:
            ExpandedWrap disabled
              push Segment
              push Offset
              retf
              Цитата Jin X @
              CS вообще по-разному можно сменить.

              Чисто формально - я бы ещё добавил INT и IRET. Они ведь тоже приводят к изменению значения CS.
                Akina, добавь :)
                Чисто формально :)

                А также:
                syscall/sysret, sysenter/sysexit, rsm, into, int1 (aka icebp), int3, bound, div/idiv (на 0), aam 0, ud2 (и прочие недействительные), все версии loadall (там, где они работали), fpu/simd-инструкции, все привилегированные инструкции в не 0-м кольце, а также даже mov (при включенном выравнивании и обращении к невыровненным данным) :whistle:
                Что я ещё забыл? :rolleyes:
                  Akina, Jin X, имхо, вы слишком разогнались! ТСу нужно не просто изменение CS, а установка конкретного значения.
                    Цитата JoeUser @
                    ТСу нужно не просто изменение CS, а установка конкретного значения.
                    Все эти методы устанавливают CS во вполне себе конкретное значение, которое можно легко как определить, так и задать перед изменением.

                    Цитата Jin X @
                    А также

                    Пока не указано явно, я стараюсь оставаться в рамках .8086...
                      Akina, я думаю, что int и даже iret ему ненужно в данном случае :)
                      JoeUser, это так, уже скорее как прикол :)
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0478 ]   [ 15 queries used ]   [ Generated: 28.03.24, 22:04 GMT ]