2015-11-18 2 views
2

В настоящее время я создаю программу для преобразования десятичной дробной части в двоичную. В настоящее время я использую метод переключения, чтобы получить 0 и 1.Intel x86 Assembly - Чтение и копирование флага переноса

Я просмотрел другие темы, которые приводят к использованию LAHF и PUSHF для доступа к флагам и их установке; однако все, что я хочу сделать, это получить текущее значение флага переноса и сохранить его в регистре (например: 1 или 0 в этой текущей позиции), который позже будет скопирован в массив. Поскольку я не слишком хорошо знаком с LAFH или PUSHF, мне было интересно, можете ли вы выполнить ту же задачу, которую я задал выше, используя LAFH или PUSHF.

Например, я хочу переместить текущий CF в eax: mov edx, cf (Я знаю, что это не работает, но я ищу что-то вроде этого). После того, как я скопировал либо 1, либо 0, я переместил его в массив, который был передан из программы на C++.

+0

Целые числа уже двоичные. «Преобразуйте целое число в двоичный», вы имеете в виду преобразование двоичного целого в представление ASCII базы 2? –

+5

Используйте инструкцию 'setc'. например, 'setc dl' –

+0

@RossRidge Извините, я имел в виду десятичное значение в двоичном формате. (База от 10 до основания 2) –

ответ

2

Я считаю, самый очевидный способ сохранить перенос в EDX является:

setc dl 
movzx edx, dl 

Это короче (6 байт), чем методы, предложенные в другие ответы, но самый короткий (5 байт) должно быть:

pushfd 
pop edx 
and edx, 1 
+3

короче: 'xor edx, edx /' generate flags '/ setc dl'. 5 байтов с хорошей производительностью (выбор 'xor' before или' movzx' после [зависит от микроархитектуры] (http://agner.org/optimize/). Кратчайший: 'sbb edx, edx' 2 байта, а также неплохая производительность Или 'sbb edx, edx/neg edx' 4 байта, если вам действительно нужно 0/1, а не 0/-1.' Sbb reg, reg' фактически используется gcc в некоторых случаях (видно при разборке '/bin/ls' например.) У меня нет голосов, или я бы отменил это. Другие ответы в основном безумны. –

+2

@AndrewNguyen: вы должны изменить свое согласие на этот ответ. Лучше. –

+0

@PeterCordes Ваш первый пример __looses__ флаг переноса через 'XOR' – Fifoernik

1

Вобщ условное задание, основанное на переносе:

mov eax, 1 
jc carry_set ; If carry is indeed set, skip the next line 
mov eax, 0 
carry_set: 

В целом, носит, как правило, используются для условных переходов, а не в качестве значения. Посмотрите, можно ли переформатировать более крупный код таким образом.

EDIT: современные процессоры Intel имеет условную команду перемещения:

mov eax, 0 
cmovc eax, 1 ; assign if carry is set 
+0

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

+1

'setc al/movzx eax, al' будет * намного лучше, чем любой из них. 'setcc' существует с 386. –

4

Почти идентичную этот вопрос: check if carry flag is set

Вы можете используете JC, JNC на ветку на основе переноса флага затем мы- или 0 в регистр, который вы хотите использовать.

Или используйте команду ADC.

mov eax, 0 
adc eax, 0 

Я добавлю, что PUSHF затем выскочить в регистр и маскировать бит вы хотите с XOR также будет работать. Подход АЦП, вероятно, лучше всего

+0

Спасибо! Это безупречно работало в моей программе сборки. –

+0

@guest Какую маску вы используете для выделения бита переноса через инструкцию 'XOR ', как указано в последнем абзаце? – Fifoernik