копирование в память в сборке - PullRequest
2 голосов
/ 24 ноября 2011

Прежде всего, используя NASM и цель x86, и работает в 16-битном реальном режиме x86. Я хочу скопировать код из одной ячейки памяти в другую, а затем выполнить вызов / jmp к месту назначения, чтобы я мог выполнить код там. Код изначально находится в 0x1000: 0x0 (сегмент: смещение). Теперь я хочу скопировать его, скажем, 0x3000: 0x0. И код размером 512 байт, точно. Я пытаюсь сделать это с помощью следующей процедуры.

org 0x500

;The code to be copied is located at 0x1000:0x0. We want to copy it to 0x3000:0x0

copy:

  mov esi,0x1000  ; source address of the code in DS:SI
  mov edi,0x3000  ; destination address of the code in ES:DI
  mov ecx,0x200   ; size of the code, 512 bytes (0x200)
  rep movsb       ; copy bytes from address in SI to address in DI.

  jmp 0x3000:0x0  ; jump to the destination , and execute the code there.

Копируемый код просто печатает строку. Так что, если приведенный выше фрагмент работает, я бы увидел эту строку на экране. Кроме того, я проверил, что скопированный код работает, и что он действительно присутствует в 0x1000: 0x0, поэтому никаких очевидных / глупых ошибок не было. Вышеприведенная процедура почему-то не работает. Возможные точки отказа, на мой взгляд, могут быть неверно указаны адреса. Я не уверен, что нужно вставить в SI и DI перед копированием. Должны ли это быть смещения или фактический адрес? Документация не проясняет это. Кроме того, я должен явно инициализировать ES и DS?

Я пробовал разные комбинации вещей, чтобы попытаться сделать это, но безрезультатно. Одним из них было это:

org 0x500

;The code to be copied is located at 0x1000:0x0. We want to copy it to 0x3000:0x0

copy:
  mov bx,0x1000
  mov ds,bx       ; set DS explicitly to 0x1000.
  mov esi,0x0     ; source address of the code in DS:SI (0x1000:0x0)
  mov bx,0x3000
  mov es,bx       ; set ES explicitly to 0x3000
  mov edi,0x0     ; destination address of the code in ES:DI (0x3000:0x0)
  mov ecx,0x200   ; size of the code, 512 bytes (0x200)
  rep movsb       ; copy bytes from address in SI to address in DI.

  jmp 0x3000:0x0  ; jump to the destination , and execute the code there.

Так что здесь я явно установил ES: DI и DS: SI. Это тоже не сработало. Я также попытался дать фактические физические адреса SI и DI, но не получилось. Теперь у меня нет вариантов. Я уверен, что здесь допущена некоторая концептуальная память, обращающаяся к ошибке, но я не могу ее уловить. (И да, скопированный код имеет размер 512 байт, необработанный двоичный код).

Спасибо.

Ответы [ 3 ]

2 голосов
/ 24 ноября 2011

Вы удостоверились, что код, который вы копируете, является либо позиционно-независимым, либо корректным по адресу 0x3000 вместо 0x1000? Некоторые инструкции (например, CALL и длинные JMP) являются абсолютными, другие (например, короткие JMP) относятся к адресу инструкции.

0 голосов
/ 29 ноября 2011

Наконец-то, странная проблема была решенаИтак, первые несколько строк программы имели следующее:

org 0x500
mov ax,cs
mov ds,ax
mov es,ax

Затем последовала процедура копирования.Я отредактировал код так: (и это сработало)

org 0x500  
xor ax,ax  ;make ax 0, instead of copying CS to it
mov ds,ax
mov es,ax

С этим изменением первая подпрограмма копирования, которую я разместил, также сработала.Хотя я не знаю почему.Я просто играл с этими значениями сегмента, и это щелкнуло.

0 голосов
/ 25 ноября 2011

Второй кусок примера кода, который вы разместили, должен работать, если флаг направления не установлен (выполните инструкцию "CLD", если это не так), и пока вы не уничтожаете свой собственный стек или что-то еще .

Если это не сработает (и, учитывая, что первый пример настолько испорчен), я бы хотел предположить, что вы допустили ошибку в другом месте (например, возможно, вы загрузили данные из неверного сектора диска). 0x1000: 0x0000, и вы правильно копируете неправильные данные или что-то в этом роде.

Вероятно, лучший совет, который вам может дать, это научиться выполнять пошаговое выполнение кода (и просматривать содержимое регистра, устанавливать точки останова, исследовать память и т. Д.) С помощью чего-то вроде отладчика, встроенного в эмулятор Bochs.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...