Сборка Intel x86 - lt, gt, eq

Я пытаюсь написать переводчик, который переводит язык VM на язык ассемблера Intel x86 (MASM). К сожалению, я не могу найти правильный перевод для lt (меньше), gt (больше) или eq (равно), но я ожидаю, что в наборе инструкций есть что-то подобное. Самое близкое, что я смог найти, это cmp (сравнить), за которым следует условный прыжок. Но ничего без прыжка.

Например, когда я хочу перевести if (x>1 и x‹3) do... код VM выглядит примерно так

push local 0
push constant 1
gt
push local 0
push constant 3
lt
and
if-goto IF_TRUE0

теперь моя проблема в том, что я не знаю, как перевести эти gt и lt, поскольку за ними непосредственно не следует прыжок, а они оба являются частью одного условия прыжка.


person CGFoX    schedule 23.10.2013    source источник
comment
Так обычно работают компьютеры.   -  person Jonathon Reinhart    schedule 23.10.2013
comment
Условные переходы являются тем, что используется для реализации операторов if/else и циклов на уровне сборки в процессорах Intel. Что именно вы ищете?   -  person Seva Alekseyev    schedule 23.10.2013
comment
Другой вариант — использовать встроенные макросы, такие как .if и т. д. См. stackoverflow.com/a/15351291/56778 для Дополнительная информация.   -  person Jim Mischel    schedule 24.10.2013


Ответы (2)


Используйте другой условный переход. Наивным переводом было бы что-то вроде

        cmp local0, 1
        jle .L1
        cmp local0, 3
        jge .L1
        ;; code of true case
.L1:

Обратите внимание, что вашему переводчику придется смотреть немного дальше, чем просто операция gt/lt и ее аргументы, чтобы понять, как следует переводить сравнение.

person gsg    schedule 23.10.2013
comment
Благодарю вас! Это единственное, что я мог придумать, но это казалось немного сложным, так как мне нужно было бы немного заглянуть вперед (как вы уже упоминали). Это самый простой способ? Неужели в сборке x86 нет простого lt/gt? - person CGFoX; 24.10.2013
comment
Нет. Однако вы можете сгенерировать ноль или единицу из условия (используя setcc), если хотите. Это будет работать немного медленнее, но ваша работа по генерации кода может быть немного проще. - person gsg; 24.10.2013
comment
Ваш код выше работает для И, но что, если два условия x>1, x‹3 связаны с ИЛИ? Я уверен, что есть простое решение, но сейчас я ничего не могу придумать. - person CGFoX; 24.10.2013
comment
Поместите новую метку .L2 в начало истинного случая и измените первый условный переход на jg .L2. - person gsg; 24.10.2013
comment
Как вы думаете, это хорошая идея написать функцию lessThan, которая оборачивает опубликованный вами код (возвращает 1, если 1-й параметр меньше, иначе 0) и использовать ее вместо lt в x86? - person CGFoX; 25.10.2013

Если вы хотите сделать перевод автоматически (вы хотите написать что-то вроде JIT-компилятора), вам нужно подумать о том, как работает инструкция «gt»:

Пример для "ГТ":

Stack before: X, Y, ...
Stack after: 1, ... if (X<Y)

Вам нужно несколько инструкций x86 для одной инструкции «LT». Пример:

  pop ax  ; this is X
  pop cx  ; this is Y
  xor dx,dx ; set edx to 0
  cmp cx,ax
  jle some_label
  mov dx,1
some_label:
  push dx

Используя 32-битный код, вы можете использовать инструкцию setgt:

pop eax  ; this is X
pop ecx  ; this is Y
xor edx,edx ; set edx to 0
cmp ecx,eax
setgt dl
push edx
person Martin Rosenau    schedule 24.10.2013