Чем dw и d d отличаются от директив db для строк?

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

Digits: db "0123456789ABCDEF"

Я определил переменную с dbэто означает определение байта. Значит ли это, что Digits переменная длиной 8 бит? Это не имеет смысла для меня, потому что:

Каждый символ в строке является символом ASCII, поэтому мне потребуется 2 байта для каждого символа. В общей сложности мне понадобится 32 байта для всей строки!

Так что это значит, когда я определяю переменную как байт? Слово? Двойное слово? Я не вижу разницы. Из-за моего недопонимания кажется излишним указывать тип данных, которые вам нужны для строки.

П.Д.: Этот вопрос не помог мне понять.

2 ответа

Решение

Один из ответов на связанный вопрос содержит цитату из примеров руководства NASM, которая действительно отвечает на ваш вопрос. В соответствии с просьбой, я расширю его для всех трех случаев (и исправлю ошибку кодирования ASCII в нижнем и верхнем регистре!):

db   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45                (5 bytes)
dw   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45 0x00           (6 bytes, 3 words)
dd   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45 0x00 0x00 0x00 (8 bytes, 2 doublewords)
dq   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45 0x00 0x00 0x00 (8 bytes, 1 quadword)

Таким образом, разница заключается в том, что при использовании он увеличивается в несколько раз по размеру элемента с нулями dd или же dw вместо db,

Согласно комментарию @Jose, некоторые ассемблеры могут использовать другой порядок байтов для dd или же dw строковые константы. В синтаксисе NASM строка всегда сохраняется в памяти в том же порядке, в котором она указана в константе в кавычках.

Вы можете собрать это с NASM (например, в плоский двоичный вывод по умолчанию) и использовать hexdump -C или что-то, чтобы подтвердить порядок байтов и количество заполнения.


Обратите внимание, что это дополнение к размеру элемента применяется к каждому элементу, разделенному запятыми. Так что, казалось бы, невинный dd '%lf', 10, 0 на самом деле собирается так:

;dd   '%lf',    10,        0
db    '%lf',0,  10,0,0,0,  0,0,0,0        ;; equivalent with db

Обратите внимание 0 до новой строки; если вы передадите указатель на это printf, строка C просто "%lf", прекращено первым 0 байт.

(write системный вызов или fwrite функция с явной длиной напечатает все это, включая 0 байты, потому что эти функции работают с двоичными данными, а не со строками C неявной длины.)

Хочу кое-что уточнить:

example: db 'ABCDE';

Всего резервируется 5 байтов, каждый из которых содержит букву.

ex2: db 1 ;

резервирует байт, содержащий 1

ex3: db "cool;

резервирует 4 байта, и каждый байт содержит букву

ex4: db "cool", 1, 3;

резервирует 3 байта?

ответы: ex4 - 6 байт

Для каждого символа в строке "0123456789ABCDEF" вам нужен всего один байт. Итак, строка будет занимать 16 байт в памяти.

В случае этой декларации:

Vark DB 1

Вы можете сделать это:

мов [vark],128

и не может:

мов [vark],1024

но в этом случае:

vark dw 1

вы можете.

Другие вопросы по тегам