Форум программистов, компьютерный форум, киберфорум
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.63/2256: Рейтинг темы: голосов - 2256, средняя оценка - 4.63
Ушел с форума
Автор FAQ
 Аватар для Mikl___
16374 / 7686 / 1080
Регистрация: 11.11.2010
Сообщений: 13,760
14.11.2013, 10:29  [ТС]
ГЛАВА 10
АРИФМЕТИЧЕСКИЕ КОМАНДЫ
(часть 2/7)


Команды ADC и SBB
(Сложение с переносом = «ADDITION with Carry»)
(Вычитание с займом = «SUBTRACT with Borrow»)
Синтаксис команд:
https://www.cyberforum.ru/cgi-bin/latex.cgi?ADC <DEST>,<SRC>

https://www.cyberforum.ru/cgi-bin/latex.cgi?SBB <DEST>,<SRC>
Возможные варианты команды ADC:
adc reg,reg/mem
adc reg/mem,reg
adc reg/mem,imm

Возможные варианты команды SBB:
sbb reg/mem,reg
sbb reg,reg/mem
sbb reg/mem,imm

Псевдокод команды ADC:
https://www.cyberforum.ru/cgi-bin/latex.cgi?DEST \leftarrow DEST + SRC + CF
Допустимые типы операндов, как в командах ADD и SUB. Аналогичны командам обычного сложения и вычитания за одним исключением, в команде ADC к сумме операндов еще прибавляется значение флага переноса CF.
Псевдокод команды SBB:
https://www.cyberforum.ru/cgi-bin/latex.cgi?DEST \leftarrow DEST - SRC - CF
А в команде SBB из разности операндов вычитается значение флага переноса CF.
Для чего нужны команды ADC и SBB?
Арифметика одинарной и многократной точности
Максимальное значение целого числа определяется числом бит, отведенных для его хранения. Если целое число хранится в одном, двух, трех и т.д. байтах, говорят, что оно имеет одинарную, двойную, тройную и т.д. точность. Микропроцессор i4004 мог обрабатывать 4-разрядные двоичные числа, действия над более длинными операндами выполнялись по частям. Микропроцессор i8080 обрабатывал 8-разрядные двоичные числа. Микропроцессоры i8086-i80286 одной командой складывали/вычитали уже числа размером в слово (16 бит), действия над более длинными операндами продолжали выполняться по частям. Начиная с i386 одной командой можно было уже сложить/вычесть числа размером в двойное слово (32 бита). Сложение и вычитание чисел других размеров, например учетверенных слов, приходилось реализовывать через сложение (вычитание) чисел размером в двойное слово. В Pentium III произошло расширение набора инструкций командами SSE (Streaming SIMID Extension), основанных на блоке 128-разрядных регистров XXM, а проблема сложения/вычитания длинных чисел осталась.
Рассмотрим сложение учетверенных слов: X=12300004F0000003h и Y=805000023000000Fh. Условно разбиваем каждое учетверенное слово на два двойных: X1=12300004h, X2=F0000003h, Y1=80500002h, Y2=3000000Fh.Сначала складываем младшие (правые) части (X2 и Y2), используя команду ADD. Может получиться единица переноса, которую надо учесть. Как это сделать? Единица переноса попадает во флаг CF, поэтому к сумме старших частей (X1 и Y1) надо добавить значение этого флага (если единицы переноса не было, то CF=0 поэтому и здесь можно прибавлять CF), именно это и осуществляет команда ADC. Поэтому старшие части чисел складываем командой ADC.
Аналогичным образом реализуется вычитание беззнаковых чисел размером в учетверенное слово, для чего используют команду SBB.
Таким образом, команды ADC и SBB значительно расширяют диапазон значений складываемых и вычитаемых чисел. С помощью команд ADC и SBB можно реализовать сложение и вычитание чисел любого размера, причем эти операции для знаковых и беззнаковых чисел реализуются одинаково.
Применение команды SBB
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
;Алгоритм поиска минимального беззнакового числа
;If (EBX<EAX) then EAX=EBX
SUB EBX,EAX ;if (EBX<EAX) CF=1 else CF=0
SBB ECX,ECX ;if (EBX<EAX) ECX=-1 else ECX=0
AND ECX,EBX ;if (EBX<EAX) ECX=EBX else ECX=0
ADD EAX,ECX ;if (EBX<EAX) EAX=EAX+(EBX-EAX) else EAX=EAX
;if (EAX<0) then EAX=ECX else EAX=EBX
CMP EAX,80000000h ;if (EAX<0) CF=1 else CF=0
SBB EAX,EAX ;if (EAX<0) EAX=-1 else EAX=0
AND ECX,EAX ;if (EAX<0) ECX=ECX else ECX=0
NOT EAX ;if (EAX<0) EAX=0 else EAX=-1
AND EAX,EBX ;if (EAX<0) EAX=0 else EAX=EBX
OR EAX,ECX ;if (EAX<0) EAX=ECX else EAX=EBX
;алгоритм получения модуля разности EAX и EBX
SUB EAX,EBX ;if (EAX<EBX) CF=1 else CF=0
SBB ESI,ESI ;if (EAX<EBX) ESI=-1 else ESI=0
XOR EAX,ESI ;if (EAX<EBX) EAX=NOT EAX else EAX=EAX
SUB EAX,ESI ;if (EAX<EBX) EAX=-EAX else EAX=EAX
Команда SALC
(Set register AL according to Carry flag)
Синтаксис команды:
https://www.cyberforum.ru/cgi-bin/latex.cgi?SALC
Семантика команды: установить регистр AL в соответствии с флагом CF.
Алгоритм работы: Если CF=1, то в AL установится значение 0FFh, если CF=0, то AL установится в 0.
Псевдокод:
https://www.cyberforum.ru/cgi-bin/latex.cgi?AL\leftarrow CF\times(-1)
Применение: SALC недокументированная команда, имеет машинный код 0D6h. Эквивалентна команде SBB AL,AL, но без изменения флагов CF, AF, PF, ZF.
Assembler
1
2
3
4
5
6
XOR EAX,EAX;MOV EAX,0
STC;установим флаг CF в 1
DB 0D6h;код команды SALC,после ее выполнения AL=0FFh
OR EAX,-1;MOV EAX,0FFFFFFFFh
CLC;сбросим флаг CF в 0
DB 0D6h; после выполнения команды SALC AL=0
Кодировка команд сложения и вычитания
Внимательно рассмотрим кодировку всех четырех команд ADD/ADC/SUB и SBB (рис. 10.2.1). Кроме битов d (бит направления) и w (бит размера) в кодировке этих команд используется бит C (бит переноса). Если бит C=1, значит при получении суммы/разности будет производится учет переноса/займа.

Рис. 10.2.1 кодировка ADD/ADC/SUB/SBB
Флаги переполнения и переноса
Так как микропроцессор не знает о том, с какими числами (со знаком или без знака) мы в данный момент работаем – он на всякий случай предполагает, что все числа со знаком. Допустим мы складываем байты.
Сложение, например, чисел 5 и 126 даст в результате то ли 8-битовое беззнаковое число 131, то ли 8-битовое число -125 со знаком. При сложении произошел перенос в знаковый разряд и получится ошибочный с точки зрения микропроцессора результат – микропроцессор выработает признак переполнения OF, свидетельствующий о том, что результат арифметических операций попал в знаковый разряд. Термины перенос и переполнение используются для близких понятий, поэтому требуются определенные уточнения.

Флаг переноса (CF) взводится только тогда, когда происходит перенос из разрядной сетки из 7, 15 или 31 разрядов в 8, 16, 32, несуществующие для регистра указанной размерности.
«Переполнение» обозначает, что результат арифметических операций либо слишком велик, либо слишком мал, чтобы его можно было корректно представить в выходном регистре. Если в результате сложения или вычитания целых чисел взвелся флаг переполнения (OF), это означает, что при «сложении по модулю 2» знаковых битов слагаемых (S1 и S2), знакового бита суммы (SR) и флага переноса (CF) получилась единица.
https://www.cyberforum.ru/cgi-bin/latex.cgi?S_{1} \oplus S_{2} \oplus S_{R} \oplus CF = OF
Перенос используют для выполнения операций с увеличенной точностью, а признак переполнения нужен для определения правильности или неправильности выполнения арифметической операции над операндами со знаком.
 OF CF Комментарий https://www.cyberforum.ru/cgi-bin/latex.cgi?S_{1}\oplus S_{2}\oplus S_{R}\oplus CF=OF
mov al,3Fh
add al,1
0 0
3Fh+1=40h
63h+1=64h(верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?0 \oplus 0\oplus 0 \oplus 0 = 0
mov al,0FDh
add al,5
0 1
0FDh+5=[1]02h (перенос)
-3+5=2 (верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 0 \oplus 0 \oplus 1 = 0
mov al,0FCh
add al,5
0 1
0FCh+5=[1]01h(перенос)
-4+5=1 (верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 0 \oplus 0 \oplus 1 = 0
mov al,40h
add al,0C0h
0 1
40h+0C0h=[1]00h(перенос)
64-64=0 (верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?0\oplus 1\oplus 0\oplus 1 = 0
mov al,0E0h
add al,60h
0 1
0E0h+60h=[1]40h(перенос)
-32+96=64(верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 0\oplus 0\oplus 1 = 0
mov al,60h
add al,0E0h
0 1
60h+0E0h=[1]40h(перенос)
96-32=64 (верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?0 \oplus 1 \oplus 0 \oplus 1 = 0
mov al,0E0h
add al,0E0h
0 1
0E0h+0E0h=[1]C0h(перенос)
-32-32=-64(верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 1\oplus 1\oplus 1 = 0
mov al,0C0h
add al,0C0h
0 1
0C0h+0C0h=[1]80h(перенос)
-64-64=-128 (верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 1\oplus 1\oplus 1 = 0
mov al,0FFh
add al,1
0 1
0FFh+1=[1]00h(перенос)
-1+1=0 (верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 0\oplus 0\oplus 1 = 0
mov al,0FFh
add al,81h
0 1
0FFh+81h=[1]80h(перенос)
-1-127=-128 (верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 1\oplus 1\oplus 1 = 0
mov al,0FFh
add al,0C1h
0 1
0FFh+0C1h=[1]C0h(перенос)
-1-63=-64 (верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 1\oplus 1\oplus 1 = 0
mov al,0FFh
add al,41h
0 1
0FFh+41h=[1]40h(перенос)
-1+65=64(верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 0\oplus 0\oplus 1 = 0
mov al,40h
add al,40h
1 0
40h+40h=80h
64+64=-128(неверно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?0\oplus 0\oplus 1\oplus 0 = 1
mov al,60h
add al,60h
1 0
60h+60h=C0h
96+96=-64 (неверно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?0\oplus 0\oplus 1\oplus 0 = 1
mov al,7Fh
add al,1
1 0
7Fh+1=80h
127+1=-128(неверно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?0\oplus 0\oplus 1\oplus 0 = 1
mov al,80h
add al,80h
1 1
80h+80h=[1]00h(перенос)
-128-128=0 (неверно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 1\oplus 0\oplus 1 = 1
Совершенно аналогично операциям сложения можно произвести ряд операций вычитания, отслеживая зависимость флага OF от наличия займов, а также знаков уменьшаемого, вычитаемого и разницы.
 OF CF Комментарийhttps://www.cyberforum.ru/cgi-bin/latex.cgi?S_{1}\oplus S_{2}\oplus S_{R}\oplus CF=OF
mov al,0E0h
sub al,20h
0 0
E0h–20h=C0h
–32–32=–64(верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1 \oplus 0\oplus 1\oplus 0 = 0
mov al,3Fh
sub al,0FFh
0 1
[1]3Fh–0FFh=40h(заём)
63–(–1)=64(верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?0\oplus 1\oplus 0\oplus 1 = 0
mov al,83h
sub al,9Ah
0 1
[1]83h–9Ah=E9h(заём)
–125–(–102)=– 23(верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 1\oplus 1\oplus 1 = 0
mov al,80h
sub al,81h
0 1
[1]80h–81h=0FFh(заём)
–128–(–127)=–1(верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 1\oplus 1\oplus 1 = 0
mov al,80h
sub al,C0h
0 1
[1]80h–0C0h=0C0h(заём)
–128–(–64)=–64(верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 1\oplus 1\oplus 1 = 0
mov al,8Ah
sub al,0A5h
0 1
[1]8Ah–0A5h=0E5h(заём)
–118–(–91)=–27(верно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 1\oplus 1\oplus 1 = 0
mov al,80h
sub al,40h
1 0
80h–40h=40h
–128–64=64(неверно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 0\oplus 0\oplus 0 = 1
mov al,80h
sub al,1
1 0
80h–1=7Fh
–128–1=127(неверно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?1\oplus 0\oplus 0\oplus 0 = 1
mov al,40h
sub al,0C0h
1 1
[1]40h–0C0h=80h(заём)
64–(–64)=–128(неверно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?0\oplus 1\oplus 1\oplus 1 = 1
mov al,60h
sub al,0A0h
1 1
[1]60h–0A0h=0C0h(заём)
96–(– 96)=–64(неверно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?0\oplus 1\oplus 1\oplus 1 = 1
mov al,7Fh
sub al,0FFh
1 1
[1]7Fh–0FFh=80h(заём)
127–(–1)=–128(неверно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?0\oplus 1\oplus 1\oplus 1 = 1
mov al,73h
sub al,0BFh
1 1
[1]73h–0BFh=0BCh(заём)
115–(–65)=–68(неверно)
https://www.cyberforum.ru/cgi-bin/latex.cgi?0\oplus 1\oplus 1\oplus 1 = 1

Команда XADD
(Обмен и сложение = «EXCHANG and ADD operands»)
Синтаксис команды:
https://www.cyberforum.ru/cgi-bin/latex.cgi?XADD <DEST>,<SRC>
Возможные варианты команды:
xadd reg/mem,reg
Алгоритм работы: операнд DEST должен быть ячейкой памяти или регистром, а операнд SRC только регистром. После сложения DEST и SRC исходное содержимое памяти (операнд DEST) переносится в операнд SRC (регистр), а полученная сумма записывается в память (на место операнда DEST). Аналогично последовательному употреблению команд XCHG и ADD.
Псевдокод команды XADD:
SRC+DEST https://www.cyberforum.ru/cgi-bin/latex.cgi?\rightarrowTEMP
SRChttps://www.cyberforum.ru/cgi-bin/latex.cgi?\rightarrowDEST
TEMPhttps://www.cyberforum.ru/cgi-bin/latex.cgi?\rightarrowDEST
;EAX=8 EBX=1Эквиваленты XADD EAX,EBX
XADD EAX,EBX XCHG EAX,EBX PUSH EAX
;EAX=9 EBX=8 ADD EAX,EBX ADD EAX,EBX
  POP EBX

Миниатюры
Электронный учебник   Электронный учебник   Электронный учебник  

Электронный учебник   Электронный учебник   Электронный учебник  

Электронный учебник   Электронный учебник   Электронный учебник  

Электронный учебник   Электронный учебник   Электронный учебник  

Электронный учебник  
Изображения
  
0
Закрытая тема Создать тему
Новые блоги и статьи
Программа для com-порта
Uhbif79 05.06.2026
Всем привет, давно хотел изучить Qt, начинал, бросал, потом снова начинал. И сейчас вот смог написать свою первую программу. До этого имел опыт программирования микроконтроллеров, писал прошивки на. . .
Транскрипция 55-минутного видео через Whisper: WhisperDesktop облажался, спас Google Colab[
anaschu 01.06.2026
Понадобилось получить текст из свежезагруженного видео на YouTube. Казалось бы, задача на пять минут. Заняла полтора часа. Делюсь опытом — может кому пригодится последовательность решений. . . .
21 мат мед. Планы на развитие модели здравоСохранения
anaschu 01.06.2026
AnyLogic: план развития симуляционной модели рабочего коллектива — динамический абсентеизм, реальные данные, три сценария сравнения Продолжаю серию постов о дискретно-событийной модели рабочего. . .
20. Мат мед. Абсентеизм как отдельный тип простоя
anaschu 29.05.2026
Апдейт модели: исправленные баги, абсентеизм и новые механизмы Продолжаю развивать ранее описанную модель рабочего коллектива на AnyLogic. За последние несколько дней был проведён серьёзный. . .
19. здоровье, усталость и психотип работника влияют на производительность предприятия, и наоборот, производительность на здоровье, усталось и психотип
anaschu 28.05.2026
Дискретно-событийная модель рабочего коллектива на AnyLogic: здоровье, выгорание, психотипы и микростимуляция Привет, коллеги. Хочу поделиться итогами нескольких недель работы над симуляционной. . .
"Прокси" для последовательного порта
Eddy_Em 28.05.2026
Эту штуку написал я достаточно давно. Но сейчас вот понадобилось настроить датчик грозы, но при этом не отключать его от "метеодемона". Соответственно, надо запустить этот "прокси": метеодемон будет. . .
Рефакторинг программы уравнивания.
Massaraksh7 26.05.2026
Пример по предыдущей записи в блоге. Но, надо заметить, что, во-первых, там оптимизация не только математики, но и работы с базой данных, и с графами, а во-вторых, это ещё не всё.
Использование TThread в Lazarus для математических вычислений.
Massaraksh7 25.05.2026
Производя рефакторинг своих программ на предмет ускорения их работы, обратил внимание на такой аспект, как сокращение времени матвычислений. Дело в том, что приходится работать с большими матрицами. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru