Как использовать инструкцию ADD с целыми числами SIGNED в сборке 8086?

Поэтому, если бы я хотел добавить два целых числа без знака, я бы просто написал

dat1 db ff
dat2 db ff
res dw ?

и в сегменте кода:

mov ax, dat1
add ax, dat2
mov dl,0
adc dl,0 ;initialize the contents of dl and use it to store the carry flag
mov byte ptr res, ax
mov byte ptr res+1, dl

НО, как бы выглядел код, если бы я хотел добавить два целых числа SIGNED? Могу ли я как-то получить доступ к флагу знака?


person localized    schedule 21.11.2012    source источник
comment
Дополнение такое же. Это замечательная вещь в математике дополнения 2s. Это просто о том, как вы интерпретируете цифры. Я не знаю о знаке флага.   -  person jcoder    schedule 21.11.2012


Ответы (2)


Сначала ошибки:

  • Он считывает 16 бит из переменных, которые выделяют только 8 бит.
  • На адрес res+1 тоже не имеет смысла писать (а на res+2).
  • also trying to write mov byte ptr addr, ax should fail
    • should be mov word ptr res, ax

Ответ на первый вопрос: ничего особенного.
add ax, bx все равно, подписаны они или нет. Самое интересное начинается при проверке регистра состояния. У вас есть флаг переноса, флаг подписи и флаг переполнения. (и более 25 несвязанных флагов). В качестве примечания: флаг переполнения устанавливается, если перенос_флага != знак_флаг для дополнений одного и того же знака. Это означает, что сложение/вычитание двух отрицательных чисел может быть интерпретировано как положительное или сложение двух положительных чисел может быть интерпретировано как отрицательное. Для слагаемых разного знака (3) + (-2) переполнения не происходит.

Доступ к флагу знака можно получить путем сравнения и ветвления:

add ax,bx  
jns process_unsigned   // or
js process_signed  

Или, если вы хотите передать знаковый бит регистра куда-то еще, вы можете
- mov cl, 16; sar ax, cl; // сместить знаковый бит над словом ax или
- add ax, ax (или shl ax,1) // сдвигаем знаковый бит из "левой" части AX в бит переноса

Кроме того, можно pushf флаг состояния, pop ax переместить его в регистр общего назначения и проверить любые отдельные биты.

person Aki Suihkonen    schedule 21.11.2012
comment
Это неверно: overflow flag is set, if carry_flag != sign_flag. -2+1=-1 OF=0 CF=0 SF=1. - person Jester; 21.11.2012

Игнорирование ошибок в примере кода (см. ответ Аки)...

Если вы пытаетесь добавить пару 24-битных чисел; тогда первое 24-битное число положительно, потому что бит знака для этого числа находится в бите 7 0, который вы перемещаете в DL (в инструкции mov dl,0). Второе 24-битное число также положительно, потому что его бит знака находится в бите 7 числа 0, которое вы добавляете к DL (в инструкции adc dl,0).

В этом случае результат сложения будет положительным (сложение 2 положительных чисел даст положительный результат), а флаг знака ЦП будет корректно показывать, что результат сложения 24-битных чисел был положительным. Флаг переноса ЦП и флаг переполнения также будут правильными (и оба будут очищены); так что вы можете протестировать их обычным образом, используя такие инструкции, как js, jg и jo (даже если вы знаете, что все они понятны и условные переходы могут быть либо удалены, либо преобразованы в jmp). Однако флаг четности и нулевой флаг процессора могут быть неправильными (например, нулевой флаг скажет только, что все старшие 8 бит равны нулю, и не скажет вам, равны ли все 24 бита нулю).

Однако, если вы думали, что добавляете 16-битные числа со знаком (и пытаетесь получить 24-битный результат), то вы делаете это неправильно и получите неправильные результаты. Чтобы добавить 16-битные числа со знаком и получить 24-битный результат, вам нужно будет «подписать расширение» 16-битных чисел, чтобы сделать их 24-битными, а не «нулевым расширением» этих чисел. Например, 16-битное (отрицательное) число 0xCDEF должно стать 24-битным (отрицательным) числом 0xFFCDEF, а не 24-битным (положительным) числом 0x00CDEF.

Другой альтернативой может быть добавление 16-битных чисел, как обычно, а затем расширение знака результата до 24-бит. Это работает только в том случае, если 16-битное сложение не переполняется, а если сложение не может переполняться, то для начала вам не нужен 24-битный результат.

person Brendan    schedule 21.11.2012
comment
24-битное число? Где бы вы взяли один из них? - person Linuxios; 21.11.2012