Как мы отслеживаем значения разных регистров при кодировании большой программы - PullRequest
1 голос
/ 18 июня 2019

здесь я представил снимок кода MSDOS, в этом типе кодового блока мы часто получаем очень разочарованную ситуацию, мы можем ясно видеть, что в строке номер строки номер 26 мы сохраняем значение DS: SI в ES: DI,но мы можем ясно видеть, что регистр SI или его содержимое находятся не рядом с этой строкой 26. Я очень часто сталкиваюсь с этим типом ситуации при понимании кодирования на ассемблере.

    01 PUSH    CS
    02 POP     DS
    03 PUSH    CS
    04 POP     ES
    05 ASSUME  DS:DOSGROUP,ES:DOSGROUP
    06 MOV     AX,OFFSET DOSGROUP:INITBLOCK
    07 ADD     AX,0Fh                  ; round to a paragraph
    08 MOV     CL,4
    09 SHR     AX,CL
    10 MOV     DI,DS
    11 ADD     DI,AX
    12 INC     DI
    13 MOV     [CurrentPDB],DI
    14 PUSH    BP
    15 PUSH    DX              ; Save COMMAND address
    16 MOV     AX,[ENDMEM]
    17 MOV     DX,DI

    18 invoke    SETMEM          ; Basic Header
    19 ASSUME  DS:NOTHING,ES:NOTHING
    20 PUSH    CS
    21 POP     DS
    23 ASSUME  DS:DOSGROUP
    24 MOV     DI,PDB_JFN_Table
    25 XOR     AX,AX
    26 STOSW              ;<--------------------here
    27 STOSB

Мы можем ясно видеть, что значение SI находится не рядом с номером строки 26. Каково решение проблем такого типа.Делаем ли мы бумажную копию значений всех регистров, которые передаются при кодировании программы, или мы возвращаемся в код и находим значение SI (или любого конкретного регистра), а затем корректируем его значение в нашем кодировании.

1 Ответ

2 голосов
/ 18 июня 2019

Чтобы ответить на заглавный вопрос: да, используйте комментарии, чтобы описать, какая логическая «переменная» будет в каком регистре для блока кода.И документируйте входы / выходы / clobbers для каждой функции.Как ;;; input: ds:si pointer to a 0-terminated string в некоторой гипотетической функции (не этой).Внутри функции для временных сообщений снова прокомментируйте место, где вы что-то вычисляете.

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


Как указывает Шут, это stos, а не movs, поэтому он не читает DS:SI.Он сохраняет только AX и AL в ES:DI ( Intel docs ).Однако этот код выглядит неработоспособным: он устанавливает DS, но не ES прямо перед этим, как если бы он ожидал, что STOS будет использовать DS:DI (чего не происходит).

Возможно, он работает впопрактикуйтесь, потому что SETMEM не на самом деле clobber ES, или не установите для него значение, которое этот код все равно хотел.Но из assume ES:NOTHING после вызова SETMEM похоже, что этот код ожидает SETMEM уничтожения ES.

Я предполагаю, что этот код взят из DOS 1.0, который вы искалив, так что, предположительно, ES все еще фактически равен CS от толчка / удара в верхней части этого блока, по счастливой случайности или что-то в этом роде.

Это тот случай, когда он пошаговов отладчике может помочь понять это. Я думаю, что встроенный отладчик BOCHS позволяет вам устанавливать точки останова где угодно, даже в коде ОС, и они работают даже с отключенными прерываниями.


Во всяком случае, есть ограничения на использование комментариев, когда все становится сложным.

Именно поэтому в реальной жизни мы оставляем оптимизацию на большие расстояния / масштабирование / постоянное распространение для компиляторов (которые превосходны при , ) и в основном беспокоятся только об микрооптимизации asm для горячих циклов (где компиляторы не всегда хороши).

...