Добавление байта (из памяти) в регистр AX (MASM)
В настоящее время я пытаюсь выяснить, как добавить первый байт в памяти, на который указывает регистр указателя SI, к текущему содержимому регистра ax.
Поэтому, если SI содержит какой-то адрес, а значения в памяти - 00 01 по этому адресу, я хочу добавить только 00 в регистр ax.
Первой инструкцией, которую попробовал я сам по сборке, была
add ax, byte ptr [SI]
но, конечно, без кубиков, так как я пытаюсь добавлять операнды разного размера.
Мой текущий обходной путь
mov dx,0000h ;empty the contents of dx
mov dl,byte ptr [si] ;get the value of the first byte in a register
add ax,dx ;perform the originally desired addition
Но это невероятно расточительно и сильно сказывается на моем количестве выполненных инструкций (это часть подпрограммы, которая выполняется много раз).
Я ограничен набором инструкций 8086, поэтому этот вопрос / ответ Питера Кордеса, который предлагает
movzx
сжатие моих первых двух строк, к сожалению, нежизнеспособно.
Помощь приветствуется.
1 ответ
Как вы говорите, если вы можете предположить, что процессор, совместимый с 386, хорошим вариантом (особенно для современных процессоров) является
movzx dx, byte [mem]
/
add ax,dx
. Если нет, я думаю, мы можем притвориться, что настраиваемся на настоящий 8086, где размер кода в байтах часто более важен, чем количество команд . (Особенно на 8088 с его 8-битной шиной). Итак, вы определенно хотите использовать
xor dx,dx
до нуля DX (2 байта вместо 3 для
mov reg, imm16
), если вы не можете полностью избежать инструкции обнуления.
Поднимите обнуление DX (или DH) из любого цикла, так что вы просто
mov dl, [mem]
/
add ax, dx
. Если функция выполняет это только один раз, вам может потребоваться (вручную) встроить функцию в сайты вызовов, которые вызывают ее в цикле, если она достаточно мала для того, чтобы это имело смысл.
Как говорит Раймонд, вы можете выбрать любой другой регистр, старшая половина которого, как вы знаете, равна нулю в этой точке вашей функции. Возможно, вы могли бы вместо
mov cl,4
если вам раньше понадобился CL=4 для чего-то еще, но вы закончили с CX к тому времени, когда вам нужно добавить в AX.
mov cx, 4
всего на 1 байт длиннее, поэтому вы получаете обнуление CH только с 1 дополнительным байтом размера кода. (против.
xor cx,cx
стоит 2 байта)
Другой вариант - байтовое добавление / adc , но он не идеален для размера кода. (Или производительность на более поздних процессорах)
add al, [mem] ; 2 bytes + extra depending on addr mode
adc ah, 0 ; 3 bytes
Это на 1 байт больше, чем если бы у вас уже был запасной регистр с верхним нулем:
mov dl, [mem] ; 2 bytes (+ optional displacement)
add ax, dx ; 2 bytes
Но с другой стороны, add / adc вообще не нуждается в дополнительном регистре.
С указателем в SI стоит поискать способы воспользоваться преимуществами
lodsb
если вы действительно оптимизируете размер кода. Что делает
mov al, [si]
/
inc si
(или вместо этого
dec si
если DF=1). Итак, вы хотите добавить в другой регистр.
xchg ax, reg
составляет всего 1 байт, но если вам нужно два свопа, он может не окупиться.