-
Я понимаю, что, вероятно, надо идти читать документацию. но честное слово это момент не могу найти ответа, а где взять толковый краткий мануал (как было в мою бытность с Z80) - не ведаю, да и условные обозначения в доках, оказывается, уже не очень понимаю, а расшифровка не по глазам. Это были извинения за то, что такой вопрос задаю. Вопрос: Есть дизассемблированный код, в нём: len - integer pNonSpace, pStart - указатели pChar > pas: len := pNonSpace - pStart + 1;
mov ecx, edi
sub exc,[ebp-$0c]
jno здесь адрес перехода на "add ecx, 01"
call @IntOver
add ecx, 01
....... Ну и далее там что-то, не важно.
-
Собственно вопрос: Какие должны быть операнды в sub exc,[ebp-$0c] чтобы после неё взвёлся флаг OF ?
Я думал, что оба операнда, например, должны быть больше MaxInt, но почему-то нет. Или exc (оно же pNonSpace) должно быть больше MaxInt, а вычитаемое (т.е. pStart) должно быть меньше MaxInt?
(ну я предполагаю, что указатели - эти беззнаковый величины же и поэтому могут быть больше, чем знаковый Int)
-
В общем спросил от отчаяния, пока писал пост - придумал как построить эксперимент, чтобы адреса в функцию передавались какие надо и проблему воспроизвёл. Как-нибудь напишу в чем было дело, глюк неожиданный и неприятный.
По моему вопросу: нужен вариант номер 2, т.е. чтобы pNonSpace было более MaxInt, а pStart - менее MaxInt
-
ну к примеру в ECX $80000000 а в памяти по адресу [EBP - $C] значение $7FFFFFFF
-
Я, признаться, никак не могу сообразить логику выставления этого флага. Ну разве что он применим (осмысленен) сугубо для signed int типов, а для unsigned int смысла не имеет?
-
( друзья, я в общем-то в теме и осознаю, что для процессора нет разницы между signed и unsigned типами, и что это лишь вопрос трактовки; но именно трактовку и "бизнес смысл" и пытаюсь понять)
-
123-124 не выставляется?
-
> Ну разве что он применим (осмысленен) сугубо для signed > int типов, а для unsigned int смысла не имеет?
Процессор не знает о том что за число (SIGNED/UNSIGNED) поэтому это возлагается на компилятор, который генерирует различные инструкции условного перехода при работе с такими типами.
К примеру
var A, B: DWORD; ... if A < B then
Здесь будет использоваться инструкция JBE в которой задействованы флаги CF и ZF, а вот для такого случая:
var A, B: Integer; ... if A < B then
Будет использоваться инструкция JLE где прыжок осуществляется уже по совокупности флагов ZF, SZ и OF
А флаги будут выставляться всегда.
-
> Inovet © (04.02.16 15:50) [6] > 123-124 не выставляется?
нет конечно
-
-
ЗЫ: в vmCMP8() происходит вычитание второго числа из первого - как раз искомый SUB
-
> [8] Rouse_ © (04.02.16 15:55)
Полез проверять.
mov eax, 124
sub eax, 1 ; Сбросился
mov eax, 124
sub eax, ecx ; Выставился. Уф.
-
> Inovet © (04.02.16 16:07) [11]
Ты точно про OF флаг говоришь? Этот код не выставляет OF флаг.
-
> [12] Rouse_ © (04.02.16 16:13) > Ты точно про OF флаг говоришь?
Блин, а я ж про CF думал.:)
-
А всё же, логика выставления OF флага?
-
> Inovet © (04.02.16 16:18) [13] > > [12] Rouse_ © (04.02.16 16:13) > > Ты точно про OF флаг говоришь? > > Блин, а я ж про CF думал.:)
Угу я даж ролик успел снять, подумал мошт у меня крыша поехала :) http://rouse.drkb.ru/tmp/1.mp4
-
> KSergey © (04.02.16 16:20) [14] > А всё же, логика выставления OF флага?
так она простая: if (!aBit && bBit && flags.SF)
flags.OF = true;
if (aBit && !bBit && !flags.SF)
flags.OF = true; т.е. смотрим старшие биты у обоих чисел (это SIGN бит и смотрим SF флаг, который выставляется от операции сложения первого и инвертированного второго числа). Грубо говоря этим мы проверяем - происходил ли переход через $80000000 (перенос бита в более старший разряд)
-
-
Давай попробую по другому, вот смотри пример от Inovet От числа 123 отнимает 124. Отнимать будем через сложение, т.е. выразим как оба этих числа (в 16 ричной) как 7B (123) и FFFFFF84 (минус 124)
сложим их - получим результат = $FFFFFFFF т.е. число минус 1 - которое полностью укладывается в диапазон 32 бит.
Теперь берем пой пример: первое число $80000000 второе $7FFFFFFF
второе инвертируем: оно становится равно $80000001
складываем - на выходе число: $100000001 - а вот оно уже в 32 бита не влезет, самый старшая единичка находится в 33-ем бите - оть это и есть переполнение.
Так понятно?
-
> А всё же, логика выставления OF флага?
Флаг OF взводится если результат не влазит в размеры операнда. Операнд для этого флага трактуется как знаковый. SInt8 = от -128 до 127 К примеру SUB (-128), 1 Результат -129 не влазит в SInt8 следовательно возводится OF. SUB 1, -127 Результат 128 не влазит в SInt8 следовательно возводится OF.
function SUB8(a,b:UInt8):UInt16; begin Result:=a-b; _ZF:=Ord(Result=0); _SF:=(Result shr 7) and 1; _PF:=PF_Table[Result and $FF]; _OF:= (((a xor b) and (a xor result)) shr 7)and 1; _CF:=(Result shr 8) and 1;
_AF:=((a xor b xor result) shr 4) and 1; end;
|