Как сохранить 4 символа в определенном двойном слове на ассемблере? - PullRequest
3 голосов
/ 23 мая 2019

В настоящее время я занимаюсь программированием ассемблера (16-бит) в DOSBox с использованием MASM.

var1 dd 'abcd'

Для приведенного выше кода MASM выдает ошибку:

A2010: синтаксическая ошибка

Что не так с синтаксисом? Я просто храню 4 символа в двойном слове.

Я делаю 16-битную сборку, так это проблема? Могу ли я использовать только db и dw, потому что другие переменные больше 16 бит?

1 Ответ

3 голосов
/ 23 мая 2019

var1 db 'abcd' помещает нужные вам байты в память в нужном вам порядке, как говорит zx485.

для чего нужны переменные, отличные от db?

Удобство написания инициализатора, dd 1234h удобнее, чем db 34h, 12h, 0, 0.

@ MichaelPetch говорит , что более поздние версии MASM действительно принимают dd 'abcd', но они этого не делаютendian переворачивает его, как это делает NASM.

NASM будет хорошо принимать mov eax, 'abcd' или dd 'abcd': многосимвольные литералы - это просто еще одна форма целочисленного литерала с первым байтом в памяти (наименее значимым), потому что x86 - это младший порядок байтов.то есть в NASM, многосимвольные целочисленные литералы имеют порядок памяти, соответствующий их порядку источника.

Но MASM обращает их вспять при использовании с dd или dw, поэтому первый символ становится наиболее значащий байт целого числа, а порядок памяти обратен порядку источника.Это может быть хорошей идеей, чтобы избежать этого даже в версиях MASM, которые поддерживают синтаксис, и использовать шестнадцатеричные коды ASCII плюс комментарий.


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

Использование var1 db ... означает, что вам придется использовать явный dword ptr каждый раз, когда вы хотите получить доступ ко всем 4 байтам с помощью mov eax, [var1].Без dword ptr [var1] MASM будет жаловаться на несоответствие размера операнда.

Но если вы объявите его как простой ярлык, не привязанный к каким-либо директивам db или dd, которые собирают байты в память, я думаю, вы можете свободноиспользуйте его с любым размером.

(Обновление: очевидно, что метка с : является ошибкой в ​​MASM вне разделов кода. Я не уверен, есть ли способ объявить просто метку данных, котораяне является «переменной» MASM. См. обсуждение в комментариях.)

;; I'm not sure this is correct, I'm making this up from memory
;; and I've never actually used MASM.  I know the syntax from SO answers.
.data
    label1:         ; "Just" a label, no data
      db 'abcd'       

    ; little-endian 'abcd'
    var2  dd 64636261h        ; no : so the symbol becomes a variable with a size from the dd

.code
func:
    mov  eax, [label1]                ; legal I think
    mov  al, [label1]                 ; also legal
    mov  eax, dword ptr [label1]      ; always works
    movzx  eax,  byte ptr [label1+2]  ; zero extend the 'c' into EAX

    inc  [label1]                  ; ERROR: ambiguous operand-size

    mov  eax, [var1]               ; fine, both operands are dwords
    mov  al, [var1]                ; ERROR: operand-size mismatch
    mov  al, byte ptr [var1]       ; load the low byte of the dword

    inc  [var1]                   ; legal: the "variable" implies dword operand size
    inc  dword ptr [var1]         ; same as above
    and  byte ptr [var1], ~20h    ; upper-case just the first character, 'abcd' into 'Abcd'

Обратите внимание, что mov eax, var1 эквивалентно mov eax, [var1] в синтаксисе MASM, но я предпочитаю делать ссылку на память явной, используя [].

...