& ldquo; WORD PTR & rdquo; vs & ldquo; WORD & rdquo; в NASM [дубликат]

Вот несколько разных способов реализации Перечисления типов .

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

function _enum(list) {       
  for (var key in list) {
    list[list[key] = list[key]] = key;
  }
  return Object.freeze(list);
}

var Color = _enum({
  Red: 0,
  Green: 5,
  Blue: 2
});

// Color → {0: "Red", 2: "Blue", 5: "Green", "Red": 0, "Green": 5, "Blue": 2}
// Color.Red → 0
// Color.Green → 5
// Color.Blue → 2
// Color[5] → Green
// Color.Blue > Color.Green → false

И вот lodash mixin , чтобы создать перечисление с использованием строки. Хотя эта версия немного больше задействована, она автоматически выполняет нумерацию. Все методы lodash, используемые в этом примере, имеют обычный эквивалент JavaScript, поэтому вы можете легко их отключить, если хотите.

function enum() {
    var key, val = -1, list = {};
    _.reduce(_.toArray(arguments), function(result, kvp) {    
        kvp = kvp.split("=");
        key = _.trim(kvp[0]);
        val = _.parseInt(kvp[1]) || ++val;            
        result[result[val] = key] = val;
        return result;
    }, list);
    return Object.freeze(list);
}    

// Add enum to lodash 
_.mixin({ "enum": enum });

var Color = _.enum(
    "Red",
    "Green",
    "Blue = 5",
    "Yellow",
    "Purple = 20",
    "Gray"
);

// Color.Red → 0
// Color.Green → 1
// Color.Blue → 5
// Color.Yellow → 6
// Color.Purple → 20
// Color.Gray → 21
// Color[5] → Blue

17
задан Linkas 9 December 2012 в 20:06
поделиться

3 ответа

Вы используете разрешительный ассемблер, похоже, моя поддержка компилятора C для встроенной сборки наверняка недовольна этим. Правильный синтаксис - BYTE PTR, чтобы сообщить ассемблеру, что значение в регистре ECX должно обрабатываться как указатель. PTR. Но это синтаксис, который является по указанному , он уже мог сказать, что вы хотели использовать его в качестве указателя, поставив [скобки] вокруг имени регистра. Использование [ecx] уже дало понять, что вы хотите сохранить нуль в адрес, предоставленный регистром ECX.

Таким образом, он знает, как использовать регистр ECX, единственный другой вещь, о которой он не знает, - это то, сколько байтов должно быть установлено на ноль. Варианты 1, 2 или 4. Вы ясно дали понять, 1. BYTE.

6
ответ дан Hans Passant 1 September 2018 в 05:17
поделиться

В MASM BYTE PTR [ecx] обращается к памяти по адресу ecx. BYTE [ecx] - синтаксическая ошибка («синтаксическая ошибка встроенного ассемблера в« первом операнде »; найдена« ['»).

В NASM или YASM BYTE [ecx] обращается к памяти по адресу ecx. BYTE PTR [ecx] - синтаксическая ошибка («ошибка: запятая, двоеточие или конец строки») в NASM, «неопределенный символ« PTR »в YASM).

В TASM, BYTE PTR [ecx ] и BYTE [ecx] эквивалентны - как память доступа по адресу ecx.

Однако, в ассемблерном Gnu-газе при использовании синтаксиса intel BYTE PTR [ecx] обращается к памяти в ecx, но BYTE [ ecx] фактически обращается к памяти по адресу ecx + 1. То есть, BYTE [ecx] эквивалентен BYTE PTR [ecx + 1], который, как представляется, не является нормальным или документированным.

Ассемблер Gnu версии 2.18, 2.24 или 2.26.1:

cat > foo.S << EOF
.intel_syntax noprefix
 movb BYTE [ecx], 0 
 movb BYTE PTR [ecx], 0 
.att_syntax prefix
EOF

as foo.S
objdump -dM intel a.out

0:  67 c6 41 01 00          mov    BYTE PTR [ecx+0x1],0x0
5:  67 c6 01 00             mov    BYTE PTR [ecx],0x0
0
ответ дан Orion Lawlor 1 September 2018 в 05:17
поделиться

Резюме:

  • NASM / YASM требует word [ecx], когда размер операнда не подразумевается другим операндом. (В противном случае [ecx] в порядке).
  • MASM / TASM требует word ptr [ecx], когда размер операнда не подразумевается другим операндом. (В противном случае [ecx] в порядке).

Каждый из них задыхается от синтаксиса другого.


ВНИМАНИЕ: Это очень странная область без каких-либо стандартов ISO или легкодоступные таблицы BNF; и я не специалист по прохождению через минные поля проприетарного синтаксиса MASM.

В вашем случае нет разницы, но оператор PTR может означать в других случаях:

http://www.c-jump.com/CIS77/ASM/Instructions/I77_0250_ptr_pointer.htm

В общем случае оператор оператора PTR принудительно обрабатывает выражение как указатель указанного типа:

 .DATA
 num  DWORD   0

 .CODE
 mov     ax, WORD PTR [num] ; Load a word-size value from a DWORD

Я думаю, что существуют также ассемблерные требования (nasm / tasm / other asm), а использование «byte ptr» более переносимо.

Также проверьте раздел 4.2.16 в книге из Индии и разделы 8.12.3 (и 8.11.3 «Типовые конфликты») в «

ОБНОВЛЕНИЕ: спасибо Фрэнку Котлеру, кажется, что NASM «использует вариант синтаксиса сборки Intel» (wiki), который не включает операцию PTR.

UPDATE1: имеется оригинальная «РУКОВОДСТВО ПО ЭКСПЛУАТАЦИИ ЯЗЫКА ASM86» от Intel, 1981-1983, оператор PTR определен на pa ge 4-15:

Оператор PTR

Синтаксис: введите имя PTR

Описание: Оператор PTR используется для определения ссылки на память с помощью определенный тип. Ассемблер определяет правильную инструкцию для сборки на основе типа операндов в инструкции. Существуют определенные случаи, когда вы можете указать операнд, который не имеет типа. Эти случаи связаны с использованием числовых или регистровых выражений. Здесь оператор PTR используется для указания типа операнда. Следующие примеры иллюстрируют это использование:

MOV  WORD  PTR  [BX], 5        ;set word pointed to by BX = 5
INC  DS:BYTE  PTR  10          ;increment byte at offset 10
                               ;from DS

Эта форма также может использоваться для переопределения атрибута type переменной или метки. Если, например, вы хотели получить доступ к уже определенной переменной слова как два байта, вы могли бы закодировать следующее:

MOV  CL, BYTE  PTR AWORD       ;get first byte
MOV  CL, BYTE  PTR AWORD + 1   ;get second byte

Значения полей:

Тип Это поле может иметь одно из следующих значений: BYTE, WORD, DWORD, QWORD, TBYTE, NEAR, FAR

name Это поле может быть: 1. Имя переменной. 2. Имя метки. 3. Адрес или регистр. 4. Целое число, которое представляет смещение.

UPDATE2: Благодаря Uni из бета-накопителя Stuttgart! Существует оригинальное руководство MACRO-86 от Microsoft (1981). Страница 3-7:

Оператор PTR можно использовать другим способом, чтобы сохранить байт при использовании прямых ссылок. Если вы определили FOO как постоянную константу, вы можете ввести оператор:

MOV [BX],FOO

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

MOV BYTE PTR [BX],FOO

MOV [BX],BYTE PTR FOO

Эти утверждения указывают MACRO-86, что FOO является байтом немедленным. Создается меньшая команда.

И страница 3-16:

Операторы переопределения

Эти операторы используются для переопределения сегмента , смещение, тип или расстояние между переменными и метками.

Указатель (PTR)

<attribute>  PTR  <expression>

Оператор PTR переопределяет тип (BYTE, WORD , DWORD) или расстояние (NEAR, FAR) операнда.

<attribute> - новый атрибут; новый тип или новое расстояние.

<expression> - это операнд, атрибут которого должен быть переопределен.

Самое важное и частое использование для PTR заключается в том, чтобы убедиться, что MACRO-86 понимает какой атрибут должен иметь выражение. Это особенно верно для атрибута type. Всякий раз, когда вы размещаете ссылки в своей программе, PTR очищает расстояние или тип выражения. Таким образом, вы можете избежать фазовых ошибок.

Второе использование PTR заключается в доступе к данным по типу, отличному от типа определения переменной. Чаще всего это происходит в структурах. Если структура определена как WORD, но вы хотите получить доступ к элементу в виде байта, PTR является оператором для этого. Однако гораздо более простой способ - ввести второй оператор, который также определяет структуру в байтах. Это устраняет необходимость использования PTR для каждой ссылки на структуру. См. Директиву LABEL в разделе 4.2.1 «Директивы памяти».

Примеры:

 CALL WORD PTR [BX][SI]
 MOV BYTE PTR ARRAY, (something)

 ADD BYTE PTR FOO,9

После прочтения этого и поиска некоторых определений синтаксиса из этих документов я думаю, что запись PTR является обязательной. Использование mov BYTE [ecx], 0 неверно в соответствии с руководством MACRO-86.

12
ответ дан Peter Cordes 1 September 2018 в 05:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: