Сборка: чтение строк инструкций по сборке

#parsing #assembly #x86

#синтаксический анализ #сборка #x86

Вопрос:

Я работаю над программой, которая должна считывать входные данные из файла, содержащего инструкции по сборке, а затем выводить, содержит ли каждая строка метку, код операции, oper1, oper2 или комментарий. Вот что у меня есть до сих пор:

         .model  small
        .8086

        .data
line        db      'LABEL=','$'
opcode      db      'OPCODE=','$'
oper1       db      'OPER1=','$'
oper2       db      'OPER2=','$'
com         db      'COMMENT=',13,10,13,10,'$'
filemsg     db      '... end of file',13,10,1Ah,'$'

        .code

start:      
        mov     ax,@data
        mov     ds,ax

progloop:
        mov     ah,8
        int     21h

        cmp     al,1Ah
        je      eof

        mov     dl,al
        mov     ah,2
        int     21h

        cmp     dl,3Ah    ; this is where I would check for a colon. incomplete for now

        cmp     dl,0Ah
        je      eol

        jmp     progloop

eol:
        mov     dx,offset line
        mov     ah,9
        int     21h
        mov     dx,offset opcode
        mov     ah,9
        int     21h
        mov     dx,offset oper1
        mov     ah,9
        int     21h
        mov     dx,offset oper2
        mov     ah,9
        int     21h
        mov     dx,offset com
        mov     ah,9
        int     21h

        jmp     progloop

eof:       
        mov     dx,offset filemsg
        mov     ah,9
        int     21h

exit:       mov     ax,4c00h
        int     21h
        end     start
  

Программа в основном должна выводиться следующим образом:

 Addval:   add   [salary],1000   ; this line has all five operands
LABEL=Y   OPCODE=Y   OPER1=Y   OPER2=Y   COMMENT=Y

testit:                         ; a label and a comment
LABEL=Y   OPCODE=N   OPER1=N   OPER2=N   COMMENT=Y
  

Я не уверен, как правильно это сделать. Должен ли я создать linemsg и отслеживать LABEL=, OPCODE= и т. Д.? Как я должен отслеживать флаги Y / N?

Ответ №1:

Самым простым, но не идеальным, было бы что-то вроде этого…

Сначала определите, есть ли комментарий к строке, а затем удалите его оттуда (либо физически, либо сократите эффективную длину строки до позиции первой точки с запятой).

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

Если что-то еще осталось, первым элементом является код операции. Если после этого что-то есть, это операнды (один или несколько, разделенные запятыми).

Это не идеальное решение, поскольку в различных ассемблерах x86 поддерживается ряд более сложных конструкций, например, если указан сегмент, будет двоеточие, которое не имеет ничего общего с метками:

 mov al, byte ptr es:[bx]
  

В приведенном выше mov al, byte ptr es нет метки.

Или у вас может быть объявлен массив, как показано ниже. Имя массива не является кодом операции, это фактически метка, но после нее нет двоеточия:

 MyArray db 1,2,3,4,5 ; array of 5 bytes
  

И вы также можете столкнуться с пунктуаторами внутри символьных и строковых литералов, которые не разделяют строку на метки, операнды и комментарии:

 MyString db ':,a;'
  

Здесь MyString db ' это не метка только потому, что после нее стоит двоеточие. a не является операндом только потому, что перед ним стоит запятая. И, наконец, ;' это не комментарий только потому, что там есть точка с запятой.

Для полной поддержки всех этих возможностей вам потребуется реализовать более сложное решение, вероятно, с использованием конечного автомата синтаксического анализа.

Комментарии:

1. Я должен не согласиться с этим ответом — по крайней мере, с первой частью. Я почти уверен, что весь смысл упражнения заключается в разработке токенизатора; распознавание ключевых слов, литералов и переменных; и, наконец, сборка кода в байт-код. Написание кода, предназначенного для определенного файла или даже определенного языка, сводит на нет цель обучения. Существует процесс написания системного программного обеспечения, и этот процесс определен по определенной причине.

2. @Sparafusile: пожалуйста, обратите внимание, что это инструкции x86 с 3 операндами (например, SHLD и SHRD), поэтому в этом отношении данная задача ограничена не только конкретным языком, но и его подмножеством. Нам ничего не сказали о намерениях, ожиданиях, токенизаторах общего назначения, фактической сборке исходного кода, и мы не в состоянии судить о SO, как обучение выполняется где-то еще, и пытаться его изменить. Я думаю, что для этого есть более подходящие способы и места. Кроме того, это задание; ожидания и процессы, существующие в отрасли, здесь не применяются в полном объеме.