Отключение локальных меток в JWasm - PullRequest
2 голосов
/ 28 мая 2020

Я получаю сообщение об ошибке при сборке кода, в котором инструкция ссылается на метку в другой процедуре.

Этот код генерирует две ошибки, ассемблер - JWasmR v2.12pre:

single segment stack                                                      
assume cs:single,ds:single,ss:single 

start:
    mov ax, cs 
    mov ds, ax                   
    mov ax, 4c00h
    int 21h

func1 proc
label1:
    jmp label2
func1 endp

func2 proc
label2:
    call label1
func2 endp

align 2                          
s16 db 256 dup (0ffh)            
single ends                             
end start

Сообщения об ошибках:

test1.asm(13) : Error A2102: Symbol not defined : label2
test1.asm(20) : Error A2102: Symbol not defined : label1

Я думаю, что каждый символ метки является локальным для соответствующего процедура. Я хотел бы отключить эту функцию глобально или обойти ее в индивидуальном порядке. Я пробовал использовать опцию -Zf, которая делает все символы publi c. Документацию можно найти здесь .

1 Ответ

3 голосов
/ 29 мая 2020

В MASM 5.1x, если вы не используете директиву .MODEL с типом языка, то метки кода внутри PROC имеют глобальную область видимости. Вот почему ваш код собирается в MASM 5.1x. В JWASM и MASM 6.1+ это немного отличается, потому что метки кода, за которыми следует :, всегда имеют локальную область видимости в PROC. Это приводит к появлению ошибок, которые вы видите. Документация MASM 6.1 охватывает эту проблему:

MASM 5.1 считает кодовые метки, определенные одним двоеточием внутри процедуры, как локальные для этой процедуры, если модуль содержит директиву .MODEL с типом языка

Решение состоит в том, чтобы использовать :: после метки, а не :, чтобы пометить метку кода как глобально определенную. В документации говорится:

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

Использование :: должно привести к ассемблированию вашего кода с помощью MASM 5.1+, 6.1+ и JWASM. Этот код:

func1 proc
label1:
    jmp label2
func1 endp

func2 proc
label2:
    call label1
func2 endp

Должен работать, если он записан как:

func1 proc
label1::
    jmp label2
func1 endp

func2 proc
label2::
    call label1
func2 endp

Вы можете использовать параметр -Zm (не путать с -mz) включает MASM 5.1 совместимость. Запуск JWASM таким образом должен позволить вашему коду ассемблировать без каких-либо изменений:

jwasm -Zm filename.asm

Использование этого метода сделает метки с локальной областью видимости в PROC с глобальной областью. Другие происходящие изменения:

Option -Zm (or setting OPTION M510) will do:
- set OPTION OLDSTRUCTS
- set OPTION DOTNAME
- set OPTION SETIF2:TRUE
- set OPTION OFFSET:SEGMENT (if no model is set)
- set OPTION NOSCOPED (if no model with language specifier is set)
- allow to define data items behind code labels
- allow "invalid" use of REP/REPE/REPNE instruction prefixes
- change precedence of [] and () operator from 1 to 9. Hence expression
  -5[bx] is parsed as (-5)[bx], while without -Zm it is
  parsed as -(5[bx]), which generates an error.

Для JWASM и MASM 6.1+ вы также можете указать опцию без области действия в верхней части модуля сборки с помощью этой директивы:

OPTION NOSCOPED

Эта опция не существует в MASM 5.1x, так как это поведение этого ассемблера. Вам придется удалить эту директиву из кода сборки при сборке с помощью MASM 5.1x. В документации MASM 6.1 этот параметр описывается следующим образом:

Информация в этом разделе применима только в том случае, если директива .MODEL в вашем коде MASM 5.1 не определяет тип языка. Без типа языка MASM 5.1 предполагает, что метки кода в процедурах не имеют «области действия», то есть метки не являются локальными для процедуры. Когда MASM 6.1 не находится в режиме совместимости, он всегда дает область видимости меткам кода, даже без типа языка. Чтобы заставить MASM 5.1 работать, укажите OPTION M510 или OPTION NOSCOPED в своем коде

...