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

Основной операцией при выполнении арифметических действий в микропроцессоре является сложение, результаты которого используются для вычитания, умножения, деления и ряда других операций.
Двоичное сложение. Теоретическая часть
Результат сложения двух одноразрядных двоичных чисел содержит 2 бита: разряд суммы (sum) и разряд переноса (carry). Таблица разряда переноса идентична таблице логического И (and), а таблица разряда суммы идентична таблице сложения по модулю 2 (xor).
A B C=A+B Carry=A and B Sum=A xor B
0 0 00 0 0
0 1 01 0 1
1 0 01 0 1
1 1 10 1 0
Для сложения двух двоичных чисел https://www.cyberforum.ru/cgi-bin/latex.cgi?A и https://www.cyberforum.ru/cgi-bin/latex.cgi?B объединяем два вентиля.
Чтобы не рисовать многократно вентили AND и XOR заменим эту схему обозначением:
Теперь мы складываем уже два четырехразрядных двоичных числа:
Полусумматор можно использовать только для сложения крайнего правого столбца (нулевой разряд): 1+1=0, и 1 идет в перенос. Для правильного поразрядного сложения во втором столбце (первый разряд) нам потребуется складывать три цифры – два разряда слагаемых и перенос из предыдущего разряда. Это же относится и к остальным столбцам. Чтобы сложить три двоичные цифры модифицируем нашу схему следующим образом:
Такая схема называется полным сумматором и обозначается вот так:
Для получения суммы двух 8-разрядных чисел нам потребуются восемь полных сумматоров. На вход для переноса в нулевом разряде подадим логический 0.
Обозначим входы 8-разрядного сумматора как https://www.cyberforum.ru/cgi-bin/latex.cgi?A_{i} и https://www.cyberforum.ru/cgi-bin/latex.cgi?B_{i}, а выходы как https://www.cyberforum.ru/cgi-bin/latex.cgi?S_{i} :
Соединив два 8-разрядных сумматора можно складывать 16-битные числа.
Чтобы использовать наш сумматор еще и для вычитания – входы https://www.cyberforum.ru/cgi-bin/latex.cgi?B дополняем следующей схемой:
Если сигнал Инверсия = 0, все восемь выходов вентилей XOR повторяют сигнал на входах. Если сигнал Инверсия = 1, все восемь выходов вентилей XOR инвертируют входной сигнал.
Для общего управления дополняем схему нашего сумматора управляющим сигналом Сложение/Вычитание. Если на управляющем входе будет 0 – будет происходить сложение, если 1 – вычитание. Различие кодировок инструкций ADD/SUB и INC/DEC всего в одном бите.
Мы создали устройство для сложения/вычитания двух чисел.
Обобщаем – суммирование двоичных многоразрядных чисел производится путем сложения одноразрядных двоичных чисел https://www.cyberforum.ru/cgi-bin/latex.cgi?A_{i}, https://www.cyberforum.ru/cgi-bin/latex.cgi?B_{i} и переноса из младшего разряда https://www.cyberforum.ru/cgi-bin/latex.cgi?C_{i}, образуя на выходе значения суммы https://www.cyberforum.ru/cgi-bin/latex.cgi?S_{i} и переноса в старший разряд https://www.cyberforum.ru/cgi-bin/latex.cgi?C_{i+1}. Функции https://www.cyberforum.ru/cgi-bin/latex.cgi?S_{i} и https://www.cyberforum.ru/cgi-bin/latex.cgi?C_{i+1} имеют вид
https://www.cyberforum.ru/cgi-bin/latex.cgi?S_{i}=A_{i}\oplus B_{i}\oplus C_{i} и https://www.cyberforum.ru/cgi-bin/latex.cgi?C_{i+1}=A_{i}B_{i}+(A_{i}+B_{i})C_{i}
При кажущейся простоте реализации сложения по такой схеме имеется один существенный недостаток: сложение организовано последовательно, при большой разрядности операндов будет нарастать задержка https://www.cyberforum.ru/cgi-bin/latex.cgi?(t_{c})_{n} выходного сигнала https://www.cyberforum.ru/cgi-bin/latex.cgi?C_{n} цепи переноса, связанная с его последовательным прохождением через одноразрядные суммирующие элементы, каждый из которых имеет задержку https://www.cyberforum.ru/cgi-bin/latex.cgi?t_{c}. В результате https://www.cyberforum.ru/cgi-bin/latex.cgi?(t_{c})_{n}=n\times t_{c}, а задержка образования n-ого разряда суммы равна:
https://www.cyberforum.ru/cgi-bin/latex.cgi?(t_{s})_{n}=t_{s}+(n-1)\times t_{c}, где https://www.cyberforum.ru/cgi-bin/latex.cgi?t_{s} – задержка суммы одноразрядного сумматора.
При большом числе разрядов https://www.cyberforum.ru/cgi-bin/latex.cgi?n времена https://www.cyberforum.ru/cgi-bin/latex.cgi?(t_{s})_{n}, https://www.cyberforum.ru/cgi-bin/latex.cgi?(t_{c})_n окажутся весьма значительными, поэтому для повышения быстродействия используют схемы с ускоренным формированием переноса.
Сложение чисел A и B в один этап
Для этого необходимо получить функцию https://www.cyberforum.ru/cgi-bin/latex.cgi?C_{n} для каждого разряда, используя формулу:
https://www.cyberforum.ru/cgi-bin/latex.cgi?C_{i+1}=A_{i}B_{i}+(A_{i}+B_{i})C_{i}
для первого разряда: https://www.cyberforum.ru/cgi-bin/latex.cgi?C_{1}=A_{0}B_{0}
для второго разряда: https://www.cyberforum.ru/cgi-bin/latex.cgi?C_{2}=A_{1}B_{1}+(A_{1}+B_{1})C_{1}=A_{1}B_{1}+(A_{1}+B_{1})A_{0}B_{0}
для третьего разряда: https://www.cyberforum.ru/cgi-bin/latex.cgi?C_{3}=A_{2}B_{2}+(A_{2}+B_{2})C_{2}=A_{2}B_{2}+(A_{2}+B_{2})(A_{1}B_{1}+(A_{1}+B_{1})A_{0}B_{0})
для четвертого разряда:https://www.cyberforum.ru/cgi-bin/latex.cgi?C_{4}=A_{3}B_{3}+(A_{3}+B_{3})C_{3}=...
и так далее.
Одновременное формирование значения переноса во всех разрядах приводит к усложнению формирования схемы переноса с каждым следующим разрядом.
Сложение чисел https://www.cyberforum.ru/cgi-bin/latex.cgi?A и https://www.cyberforum.ru/cgi-bin/latex.cgi?B в несколько этапов
Получение частичной суммы https://www.cyberforum.ru/cgi-bin/latex.cgi?A\oplus B и разрядов переноса https://www.cyberforum.ru/cgi-bin/latex.cgi?2\times AB, из частичной суммы и разрядов переноса будет сформирована новая частичная сумма и новые разряды переноса и так далее.
Процесс будет продолжаться до тех пор, пока либо частичная сумма, либо разряды переноса не станут равными нулю. Если числа https://www.cyberforum.ru/cgi-bin/latex.cgi?A и https://www.cyberforum.ru/cgi-bin/latex.cgi?B равны, то мы получим удвоение числа https://www.cyberforum.ru/cgi-bin/latex.cgi?A на первом шаге.
Вычитание чисел https://www.cyberforum.ru/cgi-bin/latex.cgi?A и https://www.cyberforum.ru/cgi-bin/latex.cgi?B произойдет аналогично сложению с той только разницей, что значение https://www.cyberforum.ru/cgi-bin/latex.cgi?B будет заменено на дополнительный к нему код.
Команды сложения и вычитания
Команды ADD и SUB

(Сложение = “Integer ADDITION”)
(Вычитание = “Integer SUBTRACTION”)
Синтаксис команд:
ADD <DEST>,<SRC>
SUB <DEST>,<SRC>
Возможные варианты команды ADD:
add reg,reg/mem
add reg/mem,reg
add reg/mem,imm

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

Семантика команды ADD: команда ADD складывает операнд DEST и операнд SRC размерностью байт, слово или двойное слово и записывает результат сложения в операнд DEST.
Псевдокод команды ADD:
https://www.cyberforum.ru/cgi-bin/latex.cgi?DEST \leftarrow DEST + SRC
Семантика команды SUB: по команде SUB из операнда DEST вычитается операнд SRC и полученная разность записывается вместо операнда DEST. Операнд DEST и операнд SRC имеют размерность байт, слово или двойное слово.
Псевдокод команды SUB:
https://www.cyberforum.ru/cgi-bin/latex.cgi?DEST\leftarrow DEST - SRC
Что произойдет, если полученная сумма окажется больше размерности операнда DEST? Например: при размере операнда DEST в 8 бит мы складываем 250 и 10, полученное число 260 (=104h=100000100b) не влезает в 8 бит, процессор отбросит самую левую единицу, а в качестве ответа будет записана искаженная сумма 04(=00000100b), но во флаг переноса CF будет записана 1.
Это сигнал о том, что получилась неправильная сумма (если бы переноса не было, тогда CF = 0). При сложении и вычитании меняются также флаг нуля ZF и флаг знака SF. Флаг нуля ZF получает значение 1, если результат оказался нулевым, и значение 0, если результат ненулевой. Во флаг знака SF заносится знаковый (самый левый) бит результата, он получает значение 1, если результат оказался отрицательным, и значение 0 при положительном результате. При выполнении сложения и вычитания могут также меняться флаг переполнения OF и флаги AF и PF.
Пример:
Code
1
2
3
99 =  0 = 00000000b ZF=1 SF=0
89 = –1 = 11111111b ZF=0 SF=1
98 =  1 = 00000001b ZF=0 SF=0
Обратите внимание скольким кодировкам соответствует команда ADD EAX/AX/AL,2
кодировкакоманда
длина
в байтах
0402 add al,2 2
66050200 add ax,2 3
0502000000 add eax,2 5
80C002 add al,2 3
6681C00200 add ax,2 4
81C002000000 add eax,2 6
6683C00200 add ax,2 5
83C002 add eax,2 3
Подробно разберем инструкцию «ADD ECX,EBX». Эта инструкция состоит из 2 байт. Первый байт содержит базовый опкод инструкции ADD r32,r/m32 он равен 03/r – его мы находим в первоисточнике «Intel 64 and IA-32 Architectures Software Developer's Manual. Volume 2A: Instruction Set Reference, A-M». В следующем байте биты 7-6 называются Mod, биты 5-3 – Reg/Opcode, биты 2-0 – R/M. Составим код команды – в поле Reg помещаем номер регистра ECX, в поле R/M – номер EBX. У нас регистровая адресация, поэтому поле Mod равно 3 (смотри таблицу 1 «Зависимость режима адресации от поля Mod»). Получаем следующий код:
 опкод d w Mod Reg R/M
bin 000000 1 1 11 001=ECX 011=EBX
hex 3 0СBh
Пишем в файл test.asm “db 3,0CBh”, компилируем и, просматривая получившийся файл test.exe программой hiew32.exe, убеждаемся в своей правоте – на экране команда add ecx,ebx:
А теперь вспомним про бит направления d, сделаем d=0 и поменяем между собой содержимое полей Reg и R/M: получим ту же команду add ecx,ebx но в другой кодировке:

 опкод d w Mod Reg R/M
bin 000000 0 1 11 011=EBX 001=ECX
hex 1 0D9h
Маленькие хитрости
Для того чтобы «спрятать» сумму https://www.cyberforum.ru/cgi-bin/latex.cgi?X и https://www.cyberforum.ru/cgi-bin/latex.cgi?Y от посторонних глаз или сократить размеры программы, помните, что эквивалентами операции https://www.cyberforum.ru/cgi-bin/latex.cgi?X+Y являются:
https://www.cyberforum.ru/cgi-bin/latex.cgi?(X \oplus Y)+2\times (X \wedge Y)
https://www.cyberforum.ru/cgi-bin/latex.cgi? (X \vee Y)+(X \wedge Y)
https://www.cyberforum.ru/cgi-bin/latex.cgi?2\times (X \oplus Y)-(X \vee Y)
Аналогично, чтобы «спрятать» разность https://www.cyberforum.ru/cgi-bin/latex.cgi?X и https://www.cyberforum.ru/cgi-bin/latex.cgi?Y от посторонних глаз или сократить размеры программы, запомните эквиваленты операции https://www.cyberforum.ru/cgi-bin/latex.cgi?X-Y:
https://www.cyberforum.ru/cgi-bin/latex.cgi? (X \oplus Y)-2\times (\bar{X} \wedge Y)
https://www.cyberforum.ru/cgi-bin/latex.cgi? X + \bar{Y} + 1
https://www.cyberforum.ru/cgi-bin/latex.cgi? (X \wedge \bar{Y})-(\bar{X} \wedge Y)
https://www.cyberforum.ru/cgi-bin/latex.cgi? 2\times(X \wedge \bar{Y})-(X \oplus Y)
https://www.cyberforum.ru/cgi-bin/latex.cgi? \bar{\bar{X}+Y}

Команды INC и DEC
(Увеличение на 1 = INCREMENT BY 1)
(Уменьшение на 1 = DECREMENT BY 1)
Следующая пара команд сложения и вычитания:
Синтаксис команд:
INC <DEST>

DEC <DEST>
Возможные варианты команды INC:
inc reg/mem
Возможные варианты команды DEC:
dec reg/mem
Псевдокод команды INC:
https://www.cyberforum.ru/cgi-bin/latex.cgi?DEST \leftarrow  DEST + 1
Псевдокод команды DEC:
https://www.cyberforum.ru/cgi-bin/latex.cgi?DEST \leftarrow DEST - 1
Семантика команд: команда INC аналогична команде ADD DEST,1, то есть увеличение значения операнда DEST в памяти или регистре на 1, а команда DEC аналогична команде SUB DEST,1, то есть уменьшение значения операнда DEST в памяти или регистре на 1 (команды INC и DEC не меняют значение флага переноса CF, эти команды занимают меньше места в памяти, но так как реализованы на другой схемотехнической базе, выполняются медленнее SUB и ADD).
Команда DEC сохраняет состояние флага CF. Это позволяет использовать команду DEC для обновления счетчиков циклов без воздействия на состояние флагов, изменяемых под воздействием арифметических операций, используемых для управления циклом. Использование команды SUB с непосредственным значением 1 в качестве операнда выполняет уменьшение, которое обновляет значение флага CF.
Если вы используете DEC для уменьшения счетчика и должны проверять исчерпался ли счетчик (то есть, не стало ли число в цикле меньше нуля?), используйте для этого флаг SF:
a1: ;тело цикла
sub count,1
jnc a1;count<0?
a1: ;тело цикла
dec count
jns a1;count<0?
Примеры:
Assembler
1
2
3
4
DEC WORD PTR A; увеличить значение в переменной A на 1
INC EAX; увеличить значение в EAX на 1
MOV AL,9; поместить в регистр AL число 9
DEC AL; в результате команды DEC содержимое AL равно 8
Таблица кодировки инструкции INC на уровне битов:
Инструкция Код Код 
увеличить значение в регистре reg на 1 1111 111w:11 000 regFEC0+rb inc r8
  FFC0+rw inc r16
  FFC0+rdinc r32
увеличить значение в ячейке памяти mem на 1 1111 111w:mod 000 r/mFE /0 inc m8
  FF /0
inc m16
inc m32
увеличить значение в регистре reg на 1
(альтернативная кодировка)
0100 0reg40+ rwinc r16
  40+ rd inc r32
А теперь рассмотрите совмещенную таблицу кодировок инструкций INC и DEC. Не правда ли, очень похоже? Различие всего в одном бите!
40+rd FEC0+rb FFC0+rd
db 40h;inc eax db 0FEh, 0C0h;inc al db 0FFh, 0C0h;inc eax
db 41h;inc ecx db 0FEh, 0C1h;inc cl db 0FFh, 0C1h;inc ecx
db 42h;inc edx db 0FEh, 0C2h;inc dl db 0FFh, 0C2h;inc edx
db 43h;inc ebx db 0FEh, 0C3h;inc bl db 0FFh, 0C3h;inc ebx
db 44h;inc esp db 0FEh, 0C4h;inc ah db 0FFh, 0C4h;inc esp
db 45h;inc ebp db 0FEh, 0C5h;inc ch db 0FFh, 0C5h;inc ebp
db 46h;inc esi db 0FEh, 0C6h;inc dh db 0FFh, 0C6h;inc esi
db 47h;inc edi db 0FEh, 0C7h;inc bh db 0FFh, 0C7h;inc edi

48+rd FEC8+rb FFC8+rd
db 48h;dec eax db 0FEh, 0C8h;dec al db 0FFh, 0C8h;dec eax
db 49h;dec ecx db 0FEh, 0C9h;dec cl db 0FFh, 0C9h;dec ecx
db 4Ah;dec edx db 0FEh, 0CAh;dec dl db 0FFh, 0CAh;dec edx
db 4Bh;dec ebx db 0FEh, 0CBh;dec bl db 0FFh, 0CBh;dec ebx
db 4Ch;dec esp db 0FEh, 0CCh;dec ah db 0FFh, 0CCh;dec esp
db 4Dh;dec ebp db 0FEh, 0CDh;dec ch db 0FFh, 0CDh;dec ebp
db 4Eh;dec esi db 0FEh, 0CEh;dec dh db 0FFh, 0CEh;dec esi
db 4Fh;dec edi db 0FEh, 0CFh;dec bh db 0FFh, 0CFh;dec edi
Мы увеличивали содержание регистра общего назначения на единицу с помощью опкода 40h, к которому прибавлялся номер регистра:
40+ rd INC r32
«+rd» означает, что номер регистра прибавляется к байту справа от знака «+». Это соответствует формуле «базовый опкод + номер регистра», которую мы использовали в главе «Команды передачи данных». Если нужно увеличить на 1 не регистр, а ячейку памяти, на которую этот регистр указывает (например [eax]), тогда ищем нужную строчку в описании инструкции INC и находим:
FF /0 INC r/m32; Increment r/m double word by 1

Зависимость режима адресации от поля Mod
Mod Адрес
0 [Reg]
1 [Reg+8-битное смещение]
2 [Reg+32-битное смещение]
3 Reg
Таблица 10.2.1
«/0» говорит о том, что поле Reg в ModR/M равно 0. «r/m32» задаёт либо регистр, либо ячейку памяти размером в двойное слово, используя поля ModR/M и, возможно, SIB. Зная это, несложно составить код:
Assembler
1
inc dword ptr [eax]
 опкод w Mod Reg/Opcode R/M
bin 1111111 1 00 000 000=[EAX]
hex FF00
«INC» можно кодировать также и с помощью опкода «FF /0» :
inc eax
 опкод w Mod Reg/Opcode R/M
bin 1111111 1 11 000 000=EAX
hex FFC0

Эквивалент inc eax Эквивалент dec eax
add eax,1 sub eax,1
sub eax,0FFFFFFFFh add eax,0FFFFFFFFh
lea eax,[eax+1] lea eax,[eax+0FFFFFFFFh]
По размеру команда INC REG занимает 1 байт, а команда ADD REG,imm8 там, где imm имеет значение от –128 до 127 (то есть там, где imm может получить знаковое расширение) – 3 байта, поэтому, с точки зрения размера, INC REG/INC REG (2 байта) предпочтительнее ADD REG,2 (3 байта), а команды DEC REG/DEC REG (2 байта) предпочтительнее SUB REG,2 (3 байта).
Последовательное применение команд NEG X и NOT X эквивалентно команде DEC X. Последовательное применение NOT X и NEG X эквивалентно команде INC X. Таким образом, повторно используя NOT и NEG, можно скрытно добавить или вычесть из X некоторую константу.
Для скрытного увеличения/уменьшения содержимого регистра DI/EDI используйте команды SCASB/SCASW/SCASD или STOSB/STOSW/STOSD. Для скрытного увеличения/уменьшения содержимого регистра SI/ESI используйте команду LODSB/LODSW/LODSD. Для одновременного увеличения/уменьшения SI/ESI и DI/EDI – команды MOVSB/MOVSW/MOVSD и CMPSB/CMPSW/CMPSD.
Для скрытного увеличения/уменьшения содержимого регистра SP/ESP используйте команды PUSH/POP PUSHF/POPF PUSHA/POPA.
Команда изменение знака NEG
(Отрицательный = «NEGATIVE»)
Еще одна команда из группы сложения и вычитания.
Синтаксис команды:
NEG <DEST>
Возможные варианты команды:
neg reg/mem
Команда NEG рассматривает операнд DEST как число со знаком и меняет этот знак на противоположный.
Псевдокод команды NEG:
https://www.cyberforum.ru/cgi-bin/latex.cgi?DEST \leftarrow 0 - DEST
Assembler
1
2
mov ah,2
neg ah ; ah=-2 (0FEh)
Четыре особых случая для команды NEG:
  1. если операнд равен –128=–28 (80h), в этом случае операнд не меняется, так как нет знакового числа +128 величиною в байт. CF=1, ZF=0, OF=1, SF=1. В этом случае флаг OF получает значение 1 (при других операндах OF=0).
  2. для числа размером в слово. Если значение операнда равно минимальному отрицательному числу -32768=–216 (8000h), то команда не меняет операнд. CF=1, ZF=0, OF=1, SF=1. В этом случае флаг OF получает значение 1 (при других операндах OF=0).
  3. для числа размером в двойное слово. Если значение операнда равно минимальному отрицательному числу -2147483648=–232 (80000000h), то команда не меняет операнд. CF=1, ZF=0, OF=1, SF=1. В этом случае флаг OF получает значение 1 (при других операндах OF=0).
  4. если операнд равен 0 команда NEG не меняет операнд. Флаг CF=0, ZF=1, OF=0, SF=0, PF=0. В этом особом случае флаг CF получает значение 0, а флаг ZF значение 1 (при других операндах CF=1 ZF=0).
 OF SF ZF AF PF CF Комментарий
mov al,80h
neg al
1 1 0 0 0 1
(1)00h-80h=80h (займ)
0-(-128)=-128 (не верно)
mov al,0
neg al
0 0 1 0 1 0
0-0=0
0-0=0 (верно)
mov al,-5
neg al
0 0 0 1 1 1
(1)00h-FBh=5(займ)
0-(-5)=5 (верно)
mov al,50h
neg al
0 1 0 0 0 1
(1)00h-50h=0B0h(займ)
0-80 =-80 (верно)
При ненулевых значениях операнда после действия команды NEG ZF=0, при вычитании любого числа из 0 возникнет займ – CF=1, если число не кратно 10h – AF=1. Флаг SF меняется как обычно – если операнд был положительным, то после действия команды NEG SF=1, если операнд был отрицательным – SF=0.
Последовательность команд эквивалентная команде NEG EAX
imul eax,–1
xor eax,–1
inc eax
not eax
inc eax
xor ebx,ebx
sub ebx,eax
xchg eax,ebx
dec eax
not eax
Получение модуля числа:
вариант 1вариант 2вариант 3вариант 4вариант 5вариант 6вариант 7вариант 8
a1: neg eaxcdq cdq
;если нельзя
использовать edx
cdq xor edx,edx mov ecx,eax cdq
js a1 xor eax,edx mov ebx,eax mov ecx,eaxor edx,1 sub edx,eax neg ecx add eax,edx
 sub eax,edx add ebx,ebx sar ecx,31imul edx cmovns eax,edx cmovs eax,ecx xor eax,edx
  and ebx,edx xor eax,ecx    
  sub eax,ebx sub eax,ecx    
Небольшой подводный камень, который нужно учитывать при получении модуля - если при работе с байтами/словами/двойными словами вам попадет число 80h/8000h/80000000h - тогда все вышеперечисленные варианты получения модуля, кроме варианта с умножением, где произойдет знаковое расширение числа на два регистра (https://www.cyberforum.ru/cgi-bin/latex.cgi?al\rightarrow ax, https://www.cyberforum.ru/cgi-bin/latex.cgi?ax\rightarrow dx:ax, https://www.cyberforum.ru/cgi-bin/latex.cgi?eax\rightarrow edx:eax), приведут к появлению в качестве модуля числа 80h/8000h/ 80000000h с установкой флагов SF=1 и OF=1, что в варианте neg/js приведет к зацикливанию, а остальные варианты выдадут неправильный модуль. Отсюда мораль - либо перед вычислением модуля делать проверку на наличие такого числа, либо предварительно делать знаковое расширение, либо обрабатывать появление флага OF, либо, если точность вычисления позволяет, а знаковое расширение сделать нельзя - увеличьте число 80h/8000h/80000000h на единицу.
Assembler
1
2
3
4
5
cdq
xor eax,edx;если eax<0 тогда edx=0FFFFFFFFh иначе edx:=0
sub eax,edx;если edx=0FFFFFFFFh тогда eax:=-eax
cdq; если eax=80000000h и только в этом случае
xor eax,edx; eax:=7FFFFFFFh
Если проверка не делается, тогда замените сочетание neg/js на neg/jl ? команда jl осуществит переход только при SF=1 и OF=0. Хотя команда jl может сработать при сочетании SF=0 и OF=1, но после neg такой комбинации флагов быть не может.

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

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

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

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

Электронный учебник  
Изображения
  
1
Закрытая тема Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru