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, но я предпочитаю делать ссылку на память явной, используя []
.