Форум: "Потрепаться";
Текущий архив: 2003.10.06;
Скачать: [xml.tar.bz2];
Вниз---|Ветка была без названия|--- Найти похожие ветки
← →
Юрий Зотов (2003-07-06 13:32) [0]Идем дальше. Предыдущий этап находится здеcь:
http://delphimaster.net/view/14-1046809017/
Продолжаем изучать основы устройства и работы коипьютера, продолжаем осваивать основы низкоуровневого программирования. Используя все тот же MK, но сопоставляя его с ПК. Сейчас наша задача - закончить рассмотрение команд перехода и подойти кследующей (и ОЧЕНЬ важной!) теме - адресации.
Простейшую команду перехода (безусловный переход) мы уже рассматривали, а когда Вы писали программы решения уравнений, то при проверке числа на ноль наверняка использовали либо команду F X=0, либо противоположную ей F X‡0. Вот это уже команды УСЛОВНОГО перехода - "перейти по указанному адресу, если содержимое RX равно (или не равно) нулю". Кроме них, в МК существуют еще команды F X>=0 и F X<0, а в ПК набор подобных команд намного шире. Перечень команд условного перехода для процессора 8088 такой: JA/JNBE, JAE/JNB/JNC, JB/JNAE/JC, JBE/JNA, JCXZ, JE/JZ, JG/JNLE, JGE/JNL, JL/JNGE, JLE/JNG, JNE/JNZ, JNO, JNP/JPO, JNS, JO, JP/JPE, JS. Мнемоника этих команд довольно простая, например: J-jump (перейти), N-not (не), G-greater (больше), E-equal (равно), L-lesser (меньше), C-carry(перенос), Z-zero (ноль), O-overflow (переполнение), P-parity (четность), S-sign (знак). Скажем, JNGE означает "перейти, если не больше и не равно", JZ - "перейти, если ноль", а JNO - "перейти, если нет переполнения". Но дело, конечно, не в количестве команд и не в их названиях (все это мы всегда можем найти в справочнике), а в том, как они работают. Вот это нам и нужно понять.
Когда-то мы уже говорили о регистре флагов и о том, что в нем существуют флаги переноса (CF) и переполнения (OF). Помимо них, в этом регистре еще есть флаги нуля (ZF - устанавливается при нулевом результате выполнения команды), четности (PF - устанавливается, если младший байт этого результата содержит четное число единиц) и знака (SF - всегда равен старшему биту результата). Вот с этими флагами и работают команды безусловного перехода. Например, пусть содержимое регистра EAX равно FFFFFFFF и выполняется такой кусок программы:
INC EAX ; увеличить EAX на 1
JZ LBL ; если ноль, перейти на адрес, помеченный в программе идентификатором LBL
После выполнения первой команды EAX будет равно нулю и выставится флаг ZF. Вторая команда проверит этот флаг, увидит, что он выставлен - и произойдет переход по адресу LBL. Все просто. Примерно так же сработает и такой кусок:
SUB EBX, EAX ; вычесть EAX из EBX и записать результат в EBX
JNE LBL ; если не равно, перейти по адресу LBL
Если EAX и EBX были равны, то после выполнения первой команды выставится флаг ZF, и перехода по адресу LBL не будет. А если EAX и EBX не были равны, то после выполнения первой команды флаг ZF, наоборот, сбросится и переход будет выполнен.
Рассмотрим маленькую иллюстрацию, которая, к тому же, послужит вступлением к нашей следующей теме - адресации. Сделайте в Delphi новый проект, дважды кликните по пустой форме и в появившемся обработчике события OnCreate напишите вот что:
procedure TForm1.FormCreate(Sender: TObject);
var
I, J: Integer;
begin // Здесь поставьте BreakPoint
I := 4;
If I > 2 then J := 1 else J := 2;
end;
Теперь в меню Delphi выберите Project | Options, в диалоге на закладке Compiler снимите птичку Optimization и нажмите ОК. Далее поставьте точку останова (BreakPoint) на строке begin (для этого щелкните по ней на левом поле редактора) и запустите программу. После остановки на BreakPoint в меню Delphi выберите View | Debug Windows | CPU - и Вы увидите окно CPU с ассемблерным кодом нашей программы, а в нем примерно вот такой кусок:
0043E334 ... push ebp ; Это точка входа в наш обработчик OnCreate. Ее адрес - $43E334.
...
0043E340 ... mov [ebp-$08], $00000004 ; Это I := 4
0043E347 ... cmp dword ptr [ebp-$08], $02 ; Сравнить I с 2
0043E34B ... jle TForm1.FormCreate + $22 ; Если меньше или равно, перейти на адрес $43E356 ($43E334 + $22)
0043E34D ... mov [ebp-$0c], $00000001 ; Это J := 1 - наша ветка then
0043E354 ... jmp TForm1.FormCreate + $29 ; Перейти на адрес 43E35D ($43E334 + $29)
0043E356 ... mov [ebp-$0c], $00000002 ( сейчас он нам неинтересен и поэтому вместо него я поставил многоточие)Идем дальше. Предыдущий этап находится здеcь:
http://delphimaster.net/view/14-1046809017/
Продолжаем изучать основы устройства и работы коипьютера, продолжаем осваивать основы низкоуровневого программирования. Используя все тот же MK, но сопоставляя его с ПК. Сейчас наша задача - закончить рассмотрение команд перехода и подойти кследующей (и ОЧЕНЬ важной!) теме - адресации.
Простейшую команду перехода (безусловный переход) мы уже рассматривали, а когда Вы писали программы решения уравнений, то при проверке числа на ноль наверняка использовали либо команду F X=0, либо противоположную ей F X‡0. Вот это уже команды УСЛОВНОГО перехода - "перейти по указанному адресу, если содержимое RX равно (или не равно) нулю". Кроме них, в МК существуют еще команды F X>=0 и F X<0, а в ПК набор подобных команд намного шире. Перечень команд условного перехода для процессора 8088 такой: JA/JNBE, JAE/JNB/JNC, JB/JNAE/JC, JBE/JNA, JCXZ, JE/JZ, JG/JNLE, JGE/JNL, JL/JNGE, JLE/JNG, JNE/JNZ, JNO, JNP/JPO, JNS, JO, JP/JPE, JS. Мнемоника этих команд довольно простая, например: J-jump (перейти), N-not (не), G-greater (больше), E-equal (равно), L-lesser (меньше), C-carry(перенос), Z-zero (ноль), O-overflow (переполнение), P-parity (четность), S-sign (знак). Скажем, JNGE означает "перейти, если не больше и не равно", JZ - "перейти, если ноль", а JNO - "перейти, если нет переполнения". Но дело, конечно, не в количестве команд и не в их названиях (все это мы всегда можем найти в справочнике), а в том, как они работают. Вот это нам и нужно понять.
Когда-то мы уже говорили о регистре флагов и о том, что в нем существуют флаги переноса (CF) и переполнения (OF). Помимо них, в этом регистре еще есть флаги нуля (ZF - устанавливается при нулевом результате выполнения команды), четности (PF - устанавливается, если младший байт этого результата содержит четное число единиц) и знака (SF - всегда равен старшему биту результата). Вот с этими флагами и работают команды безусловного перехода. Например, пусть содержимое регистра EAX равно FFFFFFFF и выполняется такой кусок программы:
INC EAX ; увеличить EAX на 1
JZ LBL ; если ноль, перейти на адрес, помеченный в программе идентификатором LBL
После выполнения первой команды EAX будет равно нулю и выставится флаг ZF. Вторая команда проверит этот флаг, увидит, что он выставлен - и произойдет переход по адресу LBL. Все просто. Примерно так же сработает и такой кусок:
SUB EBX, EAX ; вычесть EAX из EBX и записать результат в EBX
JNE LBL ; если не равно, перейти по адресу LBL
Если EAX и EBX были равны, то после выполнения первой команды выставится флаг ZF, и перехода по адресу LBL не будет. А если EAX и EBX не были равны, то после выполнения первой команды флаг ZF, наоборот, сбросится и переход будет выполнен.
Рассмотрим маленькую иллюстрацию, которая, к тому же, послужит вступлением к нашей следующей теме - адресации. Сделайте в Delphi новый проект, дважды кликните по пустой форме и в появившемся обработчике события OnCreate напишите вот что:
procedure TForm1.FormCreate(Sender: TObject);
var
I, J: Integer;
begin // Здесь поставьте BreakPoint
I := 4;
If I > 2 then J := 1 else J := 2;
end;
Теперь в меню Delphi выберите Project | Options, в диалоге на закладке Compiler снимите птичку Optimization и нажмите ОК. Далее поставьте точку останова (BreakPoint) на строке begin (для этого щелкните по ней на левом поле редактора) и запустите программу. После остановки на BreakPoint в меню Delphi выберите View | Debug Windows | CPU - и Вы увидите окно CPU с ассемблерным кодом нашей программы, а в нем примерно вот такой кусок:
0043E334 ... push ebp ; Это точка входа в наш обработчик OnCreate. Ее адрес - $43E334.
...
0043E340 ... mov [ebp-$08], $00000004 ; Это I := 4
0043E347 ... cmp dword ptr [ebp-$08], $02 ; Сравнить I с 2
0043E34B ... jle TForm1.FormCreate + $22 ; Если меньше или равно, перейти на адрес $43E356 ($43E334 + $22)
0043E34D ... mov [ebp-$0c], $00000001 ; Это J := 1 - наша ветка then
0043E354 ... jmp TForm1.FormCreate + $29 ; Перейти на адрес 43E35D ($43E334 + $29)
0043E356 ... mov [ebp-$0c], $00000002 ; Это J := 2 - наша ветка else
0043E35D ...
Мы видим последовательность команд, по одной команде в каждой строке. В первом столбце находится адрес команды, во втором - ее машинный код (сейчас он нам неинтересен и поэтому вместо него я поставил многоточие), а далее идет ассемблерный код этой команды и после точки с запятой - мои комментарии. Все числа здесь, конечно же, шестнадцатиричные (и поэтому перед ними стоит знак $).
===== см. продолжение =====
← →
Юрий Зотов (2003-07-06 13:33) [1]===== продолжение =====
Что это за филькина грамота? А это и есть код нашего метода FormCreate после его обработки компилятором.
EBP - это один из регистров CPU (регистр базы - Base Pointer). В нем хранится адрес, относительно которого рассчитываются другие адреса. Например, мы видим, что нашу переменную I компилятор разместил в памяти по адресу EBP-$8, а переменную J - по адресу EBP-$С. То есть, чтобы найти адрес I, нужно из числа, хранящегося в EBP вычесть $8. Вот это $8 называется СМЕЩЕНИЕМ и любое смещение всегда идет относительно какого-то базового адреса, а такой способ адресации называется "адресация со смещением". В строках 43E34B и 43E454 тоже используется адресация со смещением, но в качестве базового компилятор задал адрес точки входа в обработчик OnCreate (он равен $43E334), а в качестве смещения - рассчитал и указал константы $22 и $29.
Итак, в строке 43E347 команда CMP сравнивает переменную I с двойкой, просто вычисляя I - 2 и выставляя при этом флаги ZF, SF и OF. В нашем случае результат будет больше нуля и переполнения нет, поэтому все эти флаги будут равны нулю (сброшены). Далее команда JLE проверяет условие (ZF=1) or (SF<>OF). Оно не выполняется, поэтому перехода на строку 43E356 не происходит и наша переменная J получает значение 1, после чего команда JMP выполняет безусловный переход на строку 43E35D - и программа пошла работать дальше. Если бы I было равно 2, то мы получили бы ZF=1, SF=0 и OF=0, произошел бы переход на строку 43E356 и переменная J получила бы значение 2. А если бы I было меньше 2, то мы получили бы ZF=0, SF=1, OF=0 и произошло бы то же самое. И в любом случае программа продолжает работу со строки 43E35D.
Обратите внимание, что написанное нами условие if I > 2 компилятор как бы "подменил" обратным условием JLE. Почему? Да просто потому, что он так написан. А написан он так потому, что в ряде случаев такие "подмены" упрощают сам компилятор или позволяют ему построить более эффективный код. Ведь совершенно неважно, точно ли машинный код соответствует исходному, или не точно. Важно, чтобы он точно соответствовал ему ПО СМЫСЛУ, давал правильный результат и был наиболее эффективным.
И еще обратите внимание на то, что никаких переменных I и J в машинном коде уже нет. Точнее, они, конечно, есть, но в виде АДРЕСОВ, а не в виде каких-то имен. Поэтому иногда задаваемые вопросы типа "как получить имя переменной, зная ее адрес" (да еще в чужой программе) по меньшей мере просто наивны. И по той же причине (а также и по куче других причин) ТОЧНЫЙ обратный перевод машинного кода на язык высокого уровня (декомпиляция) невозможен. Возможна СМЫСЛОВАЯ, но не точная декомпиляция.
Кое-что о защите и взломе программ. Предположим, Ваша программа имеет суперсложную систему защиты, но свою легальность проверяет таким образом:
if ПРАВИЛЬНЫЙ_РЕЗУЛЬТАТ_СИСТЕМЫ_ЗАЩИТЫ then РАБОТАТЬ else НЕ_РАБОТАТЬ;
Как Вы теперь уже понимаете, Ваш оператор if компилятор превратит в какую-то команду условного перехода, например, в JNE (переход, если не равно). Что делает хакер? Он отыскивает в коде Вашей программы это место и код команды JNE заменяет кодом обратной ей команды JE (переход, если равно). Вот и все, программа взломана. Ветки then и else поменялись местами и вся Ваша суперпуперзащита оказалась попросту ненужной - потому что ее никто даже и не пытался ломать, ее просто обошли. Так что помимо самой системы защиты нужно еще сделать так, чтобы хакеру было очень трудно отыскать то место, где проверяется результат ее работы.
===== см. окончание =====
← →
Юрий Зотов (2003-07-06 13:34) [2]===== окончание =====
Ну вот, пожалуй и все о командах перехода. Они довольно просты, но теперь, зная о них, мы с Вами должны понимать "внутреннюю" сущность таких операторов, как if, case, goto, for, while, repeat и им подобных. Компилятор превращает их в набор команд, которые сначала вычисляют условие перехода, а затем выполняют (или НЕ выполняют) сам переход. Только и всего. Причем заметьте - совершенно неважно, на каком именно языке эти операторы изначально были написаны и как они на этом языке называются - case, select или как-то еще. Какая разница? После компиляции они все равно превратятся практически в один и тот же набор команд (ну, возможно, с мелкими отличиями). Поэтому, например, споры о том, какой язык лучше, Паскаль или Си чаще всего бывают просто бессмысленны. Если уж сравнивать, то не языки, а компиляторы - какой работает быстрее, какой строит более эффективный код и т.д. Причем даже не обязательно компиляторы с разных языков, потому что два компилятора с одного и того же языка по своим конечным результатам запросто могут отличаться друг от друга гораздо сильнее, чем два компилятора с разных языков.
Почему здесь я говорю, что циклы тоже связаны с переходами? Потому что, когда компилятор строит код цикла, он обязательно вставляет в него две вещи - проверку условия окончания цикла и команду перехода. Если цикл закончен, то происходит переход на команду, следующую за телом цикла, а если не закончен - то на команду, стоящую в начале цикла, вот и все. Например, напишите в том же методе FormCreate любой цикл и посмотрите, как он выглядит в ассемблерном виде.
Кстати, о циклах for. Они всегда имеют переменную - счетчик цикла. Но где эта переменная размещается? Ясно, что наиболее выгодно разместить ее не в памяти, а прямо в одном из регистров CPU - тогда все операции с ней будут происходить быстрее. Кроме того, выгоднее строить цикл, не увеличивая, а уменьшая значение счетчика. Тогда по завершении цикла он окажется равным нулю, будет выставлен флаг CF и для проверки условия выхода не потребуется специальных команд - достаточно будет команды JZ (или JNZ). Именно так и поступает компилятор Delphi, если в опциях проекта включена оптимизация. Но ведь после завершения такого цикла тот же самый регистр, в котором хранился счетчик будет использован уже для чего-то другого, а сам счетчик как бы "исчезнет". Вот почему в таких случаях говорят, что значение счетчика цикла после выхода из цикла будет неопределенным (то есть, любым). И вот почему компилятор в таких случаях просит, чтобы счетчик цикла был объявлен, как простая локальная переменная - потому что непростую он не может разместить в регистре, а нелокальную не имеет права в нем размещать, иначе ее изменения будут потеряны, что может нарушить логику программы.
И домашнее задание.
1. В прошлый раз мы писали МК-программы для решения линейного уравнения AX+B=0 и квадратного уравнения AX^2+BX+C=0. Если в квадратном уравнении задать A=0, то оно превращается в линейное, но решение все равно имеет. Напишите программу решения квадратного уравнения, учитывающую эту возможность.
2. Написать в рассмотренном выше методе FormCreate цикл for, а затем сравнить его ассемблерный код при включенной и отключенной оптимизации, а также в случаях, когда счетчик цикла объявлен, как локальная и как глобальная переменная. Обязательно обратите внимание на сообщения компилятора, переведите их на русский язык, разберитесь почему они возникают и какой имеют смысл.
3. Напишите в рассмотренном выше методе FormCreate следующее:
procedure TForm1.FormCreate(Sender: TObject);
begin
if Sender = Self then Halt
end;
Мы получили программу, которая запускается и тут же завершается. То есть, как бы "защищенную" программу, которая как бы проверила свою легальность и работать отказывается. Задание - "взломать" эту программу. То есть, заставить ее работать, исправляя не ее исходный текст, а ее машинный код. Для исследования машинного кода используйте отладчик Delphi и окно CPU, а для его правки - любой HEX-редактор. Подсказка - для "взлома" достаточно найти команду jnz TForm1.FormCreate+19 (ее машинный код $7505) и заменить ее обратной командой jz (ее машинный код будет $7405). Задание это не такое простое, может и не получиться. Ничего страшного, польза будет уже от того, что Вы покопаетесь в машинном коде.
← →
SPeller (2003-07-06 16:35) [3]Оффтопик, но всё же. Может, у кого-то остались первые три ветки с уроками - интересно мне вдруг стало, хочу поделать. Чтобы не засорять форум, прошу отослать их мне на мыло. Буду очень признателен.
← →
Palladin (2003-07-06 16:42) [4]http://www.baseprogram.narod.ru
← →
Anatoly Podgoretsky (2003-07-06 16:43) [5]Вроде бы кто то делал сайт.
← →
SPeller (2003-07-06 16:50) [6]Спасибо. Бум учиться уму-разуму :)
← →
Юрий Зотов (2003-07-06 17:13) [7]Блин, нашел досадную "очепятку"...
В последнем абзаце, перед домашним заданием:
"Тогда по завершении цикла он окажется равным нулю, будет выставлен флаг CF..."
Конечно, флаг ZF, а не CF. Остальное верно.
← →
k-man (2003-07-06 20:56) [8]Спасибо пребольшое Юрию Зотову.
Я увидев эту ветку пристально изучил ее содержимое немного покраснев от названия - все-таки год стажа. Тем не менее узнал много нового.
← →
Юрий Зотов (2003-07-07 06:15) [9]Up.
← →
Skier (2003-07-07 08:13) [10]Юрию Зотову большое решпектование !
← →
Polevi (2003-07-07 10:16) [11]с удовольствием прочел
← →
AlexRush (2003-07-07 12:23) [12]Небольшое исследование оптимизации dcc32 14.0:
Код на паскале:
program Project2;
function TestProc1(param32bit1,param32bit2:CARDINAL):CARDINAL;export;
var val32bit1,
val32bit2:CARDINAL;
begin
val32bit1:=param32bit2;
val32bit1:=val32bit1+1;
val32bit2:=param32bit2+param32bit1;
end;
EXPORTS TestProc1;
begin
( 1,2)Небольшое исследование оптимизации dcc32 14.0:
Код на паскале:
program Project2;
function TestProc1(param32bit1,param32bit2:CARDINAL):CARDINAL;export;
var val32bit1,
val32bit2:CARDINAL;
begin
val32bit1:=param32bit2;
val32bit1:=val32bit1+1;
val32bit2:=param32bit2+param32bit1;
end;
EXPORTS TestProc1;
begin
TestProc1(1,2);
end.
Код, сгенерированный БЕЗ оптимизации:
00401E18 public TestProc1
00401E18 TestProc1 proc near ; CODE XREF: CODE:00401EA2p
00401E18
00401E18 var_14 = dword ptr -14h
00401E18 var_10 = dword ptr -10h
00401E18 var_C = dword ptr -0Ch
00401E18 var_8 = dword ptr -8
00401E18 var_4 = dword ptr -4
00401E18
00401E18 push ebp
00401E19 mov ebp, esp
00401E1B add esp, 0FFFFFFECh
00401E1E mov [ebp+var_8], edx
00401E21 mov [ebp+var_4], eax
00401E24 mov eax, [ebp+var_8]
00401E27 mov [ebp+var_10], eax
00401E2A inc [ebp+var_10]
00401E2D mov eax, [ebp+var_8]
00401E30 add eax, [ebp+var_4]
00401E33 mov [ebp+var_14], eax
00401E36 mov eax, [ebp+var_C]
00401E39 mov esp, ebp
00401E3B pop ebp
00401E3C retn
00401E3C TestProc1 endp
Код, сгенерированный C оптимизацией:
00401E18 public TestProc1
00401E18 TestProc1 proc near ; CODE XREF: CODE:00401E7Ep
00401E18 retn
00401E18 TestProc1 endp
Отак - то ! :)))))))))
← →
AlexRush (2003-07-07 13:19) [13]Идеологический вопрос по оптимизациив dcc32 к Юрию Зотову и всем остальным:
Паскаль в конструкции CASE не позволяет использовать переменые языка:
var VarVal:integer;
....
case SomeOne of
001 : do1;
002 : do2;
VarVal ( param32bit1,param32bit2:CARDINAL)Идеологический вопрос по оптимизациив dcc32 к Юрию Зотову и всем остальным:
Паскаль в конструкции CASE не позволяет использовать переменые языка:
var VarVal:integer;
....
case SomeOne of
001 : do1;
002 : do2;
VarVal : do3;// CONSTANT EXPRESSION EXCEPTED
end;
При реализации оператора выбора на ассемблере часто применяют карту переходов. Это может съесть много памяти, но в отдельных случаях прирост в скорости коллосальный. Например, В MFC и VCL карты переходов строятся в главной оконой процедуре для обработки сообщений системы.
В dcc32 case реализован классическим способом:
function TestProc1(param32bit1,param32bit2:CARDINAL):CARDINAL;export;
var val32bit1:cardinal;
begin
case param32bit1 of
$0F0F0F0F: val32bit1:=1;
$0A0A0A0A: val32bit1:=7;
$0E0E0E0E: val32bit1:=3;
end;
result:=val32bit1+param32bit2;
end;
С оптимизацией:
00401E18 public TestProc1
00401E18 TestProc1 proc near ; CODE XREF: CODE:00401EA7p
00401E18 sub eax, 0A0A0A0Ah
00401E1D jz short loc_401E34
00401E1F sub eax, 4040404h
00401E24 jz short loc_401E3B
00401E26 sub eax, 1010101h
00401E2B jnz short loc_401E40
00401E2D mov ecx, 1
00401E32 jmp short loc_401E40
00401E34 ; -----------------------------------------------------------------
00401E34
00401E34 loc_401E34: ; CODE XREF: TestProc1+5j
00401E34 mov ecx, 7
00401E39 jmp short loc_401E40
00401E3B ; -----------------------------------------------------------------
00401E3B
00401E3B loc_401E3B: ; CODE XREF: TestProc1+Cj
00401E3B mov ecx, 3
00401E40
00401E40 loc_401E40: ; CODE XREF: TestProc1+13j
00401E40 ; TestProc1+1Aj ...
00401E40 lea eax, [edx+ecx]
00401E43 retn
00401E43 TestProc1 endp
Так вот собственно, вопрос: Есть ли настройка/опция компилятора, с которой case"ы будут переводится в карты переходов ?
Кстати, С Оптимизацией код result:=val32bit1+param32bit2; преобразуется вlea eax, [edx+ecx]
, в то время как без оной:
00401E55 mov eax, [ebp+var_10]
00401E58 add eax, [ebp+var_8]
00401E5B mov [ebp+var_C], eax
00401E5E mov eax, [ebp+var_C]
Использование lea меня порадовало :)
← →
AlexRush (2003-07-07 13:24) [14]Продолжение вопроса:
Если все-таки карты переходов не применяются, а идет поэлементное сравнение, то почему бы не добавить возможность использовать в case переменные ? IMHO было бы удобно. Или это противоречит како-либо парадигме програмирования ??
← →
VD601 (2003-07-07 22:36) [15]Ура! Юрий, Вы молодец! Ветку Ап! ЮЗ тоже! Качай его, ребята!!!
← →
Kair (2003-07-09 20:58) [16]Че та хотел спросить, но забыл. :)
← →
Makhanev A.S. (2003-07-10 00:10) [17]Отличная ветка, одна из лучших!
Up!
← →
Marser (2003-07-10 00:23) [18]Удалено модератором
Примечание: До тех пор пока не будут принесены публичные извинения за атаку на форум, игнорирование распоряжений модераторов, нападки на модераторов, призывы к другим участика по организации флудаа, тебе и Malder писать в форумы не надо, Аристарх свои извинения принес.
← →
pasha_golub (2003-07-10 17:51) [19]Cool ;-)
← →
Skier (2003-07-11 10:54) [20]Up.
← →
Юрий Зотов (2003-07-12 11:03) [21]Up. Пока в архив не свалилось.
И приглашение к обсуждению - см. здесь:
http://delphimaster.net/view/14-1046809017/
← →
Юрий Зотов (2003-07-21 15:33) [22]Снова Up.
← →
iNew (2003-07-21 17:33) [23]Просьба у кого остались предыдущие 4 ветки скиньте на мыло.
P.S. http://www.baseprogram.narod.ru не работает.
← →
Юрий Зотов (2003-07-27 10:43) [24]Что-то нет никаких вопросов...
Народ, а в этом проекте вообще кто-нибудь, кроме меня, остался?
Или стрельба в воздух идет? Пожалуйста, отзовитесь, но только те, кто ДЕЙСТВИТЕЛЬНО эти материалы читает, честно в них разбирается, честно выполняет все задания и т.д.
← →
Marser (2003-07-27 11:33) [25]
> Marser © (10.07.03 00:23)
> Удалено модератором
> Примечание: До тех пор пока не будут принесены публичные
> извинения за атаку на форум, игнорирование распоряжений
> модераторов, нападки на модераторов, призывы к другим участика
> по организации флудаа, тебе и Malder писать в форумы не
> надо, Аристарх свои извинения принес.
Очень прошу модераторов вырвать это и подобные сообщения с корнем, а то нехорошие воспоминания в голову сразу лезут...
← →
Marser (2003-07-27 12:13) [26]
> Юрий Зотов ©
Почитываем потихоньку...Многое ещё в школе было, кое-что сам и в универе ещё много будет...
← →
Vlad Oshin (2003-07-27 16:34) [27]
> Юрий Зотов © (27.07.03 10:43)
Читаю всегда, но вот беда - все понятно.
То есть дело вот как обстоит. Как в университете перед экзаменом.
Читаю - понятно, листаю, листаю - понятно, еще листаю - непонятно. Возвращаюсь - понятно. Читаю подряд - понятно, понятно.. оба на! ничего не понял...
Вот Ваши уроки понятны. Но смотрю какие-нибудь исходники из сети - непонятно...
....Сильно жду про адресацию :)...
← →
VD602 (2003-07-27 22:04) [28]> Народ, а в этом проекте вообще кто-нибудь, кроме меня, остался?
Да, можете быть уверены. Более того - с течением времени т.н. "курс ЮЗ" будет приобретать все большую популярность.
← →
Sl1der (2003-07-27 23:36) [29]Я читаю. Жду следующего этапа. Может какие-нибудь задачки на этот урок, пока новый не готов.(желательно поинтереснее)
← →
Юрий Зотов (2003-07-27 23:44) [30]> Sl1der (27.07.03 23:36)
А программу уже взломали (задание №3)?
Если нет - ломайте. Если да, то хотелось бы знать, было ли это сложно и что именно было самым сложным?
← →
race1 (2003-07-28 08:49) [31]>Юрий Зотов © (27.07.03 23:44)
Если нет - ломайте. Если да, то хотелось бы знать, было ли это сложно и что именно было самым сложным?
самым сложным было понять как ломаются другие программки без исходных кодов в Hex едиторах :)) когда после 20-ой замены 7505 на 7405 программа запустилась ;)
← →
Юрий Зотов (2003-07-28 09:04) [32]> race1 © (28.07.03 08:49)
С помощью внешнего отладчика, дизассемблера, головы и знаний. Вот поэтому настоящий хакер - это просто-напросто высококвалицифицированный программист. Чем и отличаеся от кулхацкера.
← →
Bel (2003-07-28 10:01) [33]> Народ, а в этом проекте вообще кто-нибудь, кроме меня, остался?
Внесу и свои 5 копеек. Не сомневайтесь, остались, и многие.
Для меня это в основном вспоминание того, что проходил в институте, но есть и кое-что новое.
← →
AlexRush (2003-07-28 10:50) [34]> Юрий Зотов © (27.07.03 10:43)
> Что-то нет никаких вопросов...
- ну как это нет, я вот свои задал две недели назад....
2Юрий Зотов ©: Так все-таки, что по повду AlexRush © (07.07.03 13:24) ?
← →
Юрий Зотов (2003-07-28 11:45) [35]> AlexRush © (28.07.03 10:50)
Дружище, так ведь это уже разговор на уровне языково-компиляторных концепций, совсем не для начинающих. Тема интересная, но все же для другой ветки.
← →
chs2r (2003-07-28 15:04) [36]а где предыдущие уроки найти?
по первой ссылке пишут удалено или перемещено
← →
AlexRush (2003-07-28 15:09) [37]Юрий Зотов © (28.07.03 11:45)
> Тема интересная, но все же для другой ветки.
- так значит поднимем тему ? Она для меня действительно интересна. И, думаю, не только мне.
← →
Юрий Зотов (2003-07-28 15:19) [38]> chs2r © (28.07.03 15:04)
Внизу страницы есть ссылка на архивы. Увы, пока придется искать в них. Нужны такие ссылки:
http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1035122594&n=3
http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1035226023&n=3
http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1035836141&n=3
http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1038768556&n=3
Вопрос с централизацией "уроков" решается, но, увы, еще не решен. Так что пока см. архивы и ориентируйтесь по номерам ID.
> AlexRush © (28.07.03 15:09)
Давайте поднимем, действительно интересно. Может, и я че умное вякну, а уж других-то наверняка послушаю с удовольствием.
← →
AlexRush (2003-07-28 16:59) [39]2Юрий Зотов © (28.07.03 15:19) - Ок, пришлашаю на http://delphimaster.net/view/14-1046809017/
← →
Malder (2003-07-28 17:53) [40]Не по моей вине и к моему удивлению произошли странности с сайтом http://www.baseprogram.narod.ru
Сейчас работа восстановлена.
to Юрий Зотов
пока я поддерживаю сайт, но ищется человек, который этим будет вместо меня заниматься
← →
Malder (2003-07-28 17:55) [41]забыл, что я типа в игноре здесь. В общем, если у модераторов совсем крыша от солнца слетела - то удаляйте
← →
Юрий Зотов (2003-07-28 18:58) [42]> Malder © (28.07.03 17:53)
Очень здорово и спасибо, а то видите какие тут проблемы начались... Просьба - если не сложно, пока продолжайте поддержку, ладно? Или откликнется кто-то другой, или вопрос решится здесь.
О прочем - по мылу.
← →
AlexRush (2003-07-28 19:50) [43]2Юрий Зотов © (28.07.03 18:58) - Нехочу показаться назойливым, но все же мне интересно Ваше мнение по поводу http://delphimaster.net/view/14-1046809017/
← →
Marser (2003-07-28 20:02) [44]
> Malder © (28.07.03 17:55)
> забыл, что я типа в игноре здесь. В общем, если у модераторов
> совсем крыша от солнца слетела - то удаляйте
Будьте спокойны - мои переговоры с модераторами завершились мирно ещё 12 июля, вы чисты перед ними. А произошедшее все-таки можно простить.
← →
AlexRush (2003-07-29 13:15) [45]UP
← →
VD602 (2003-07-29 14:54) [46]Ух ты! Оказывается, когда пишется "jle +$XX" - это смещение относительно текущей команды и константа $XX равна не адресу перехода, а (адрес_перехода - длина_команды_jle), чтобы сработал алгоритм
1. Выполнить команду, адрес которой хранится в СК.
2. Увеличить значение СК на длину только что выполненной команды.
3. Повторить, начиная с п.1.
Я ПРАВ??
P.S. Кстати, почему у Вас компилятор пишет адреса со смещением относительно точки входа jle TForm1.FormCreate + $22, а у меня относительно текущей команды? Я что-то не нашел такой установки CPU-window.
← →
VD602 (2003-07-29 14:57) [47]Упс, не сработал после второй строки.
← →
VD602 (2003-07-29 15:13) [48]В смысле </B> не сработал :))
Вот же руки сегодня :)
← →
Daniel (2003-07-29 19:45) [49]Есть! Взломал!
Правда пошел на маленькую хитрость: перед строкой
if Sender = Self then Halt
Вставил
I := $78563412
И после этого в HEX-редакторе искал последовательность 12 34 45 78
То, что 12345678 надо писать в обратном порядке я понял после нескольких экспериментов. Я так понял, то это из-за того, что в памяти значения хранятся начиная с младшего байта.
Еще пробовал искать последовательность 3B 45 FC 75 05
(это cmp eax, [ebp - $04]; jnz +$05), но таких слишком много.
Еще была идея искать вызов call @Halt0;
Не получилось потому, что машинный код этой команды меняется в разных местах программы (наверное в аргументе call указывается смещение относительно текущей команды), поэтому "не зная точно кода" этого не найти.
P.S. Почему компилятор пишет (как у VD602) jmp +$05, а если я напишу
asm
jmp +$05;
end;
Выводится ошибка несоответствия команды и операнда?
А так все нормально и хорошо, не понял только задание из этапа 3:
Написать на Паскале функцию, вычисляющую машинное эпсилон для чисел типа Extended. При вычислениях учеть реально используемый аппаратный тип FPU.
Это как?
← →
Daniel (2003-07-29 19:51) [50]Извиняюсь, фразу "в HEX-редакторе искал последовательность 12 34 45 78"
Читать как
"в HEX-редакторе искал последовательность 12 34 56 78"
← →
Юрий Зотов (2003-07-29 22:27) [51]> и константа $XX равна не адресу перехода, а (адрес_перехода -
> длина_команды_jle), чтобы сработал алгоритм...
> наверное в аргументе call указывается смещение относительно
> текущей команды
Тэкс... хорошо... я потираю руки и хитро улыбаюсь в седую бороду. Как говорил кот Матроскин: "Урра!!! Зарработало!!!"
Работает метода-то! Народ сам (!) начинает доходить вот уже до таких вещей! Своей головой!
И ето радовает. Чегтовски.
Народ! Вы на верном пути, вот ей-же. Только не расслабляться - сидеть, пыхтеть, потеть, и думать, думать, думать...
Вот мы и созрели до понимания перемещаемого кода. Значит, пора говорить об адресации... сначала на примере МК, а там к указателям и хипу подберемся. И знаменитый PChar заодно щелкнем, просто по дороге. Потом адресное пространство... процессы... классы и VMT... DLL... эх-ма!
Значит, так - адресацию начнем в следующем этапе (уже готовлю), а по поводу вопроса: "При вычислениях учеть реально используемый аппаратный тип FPU" вот что - перечитайте статью Антона Григорьева еще раз, очень вдумчиво (она того заслуживает, честное слово). Там сказано про управляющее слово сопроцессора. Вот это и есть то самое.
И еще:
> Я так понял, то это из-за того, что в памяти значения хранятся
> начиная с младшего байта.
Так и есть. Все процессоры семейства x86 имеют такую аппаратную особенность (но для других процессоров это может быть и иначе). В окне CPU отладчика Delphi можно щелкнуть правой кнопкой мыши и выбрать способ показа 4-байтовых слов - побайтно, пословно или целиком. В побайтном увидим точно то, что реально лежит в памяти, в пословном - меняются местами 2-байтовые слова (но не меняются байты внутри этих слов), а целиком - видим целые числа в привычной нам "человеческой" записи (только в HEX, конечно).
← →
Anatoly Podgoretsky (2003-07-29 22:58) [52]VD602 (29.07.03 14:54)
Ух ты! Оказывается, когда пишется "jle +$XX" - это смещение относительно текущей команды и константа $XX равна не адресу перехода, а (адрес_перехода - длина_команды_jle), чтобы сработал алгоритм
Обяснение это следуюещее, пусть по адресу 100 находится эта команда, а перейти нам надо на адрес 107, по в процессоре проиходит следующее
1. процессор извлекает команду jle, IP становится равным 101
2. после декодирования команды, процессор видит, что надо извлечь адрес (смещение) перехода, IP становится равным 102
3. процессор прибавляет смещение к текущему значению IP - IP=102+5-107
4. процессор начинает извлекать команду по новому текущему адресу, который равен в данный момент 107
Что и требовалось сделать, естественно компилятор/транслятор автоматически отсчитывает адреса и производит расчет необходимого смещения для осуществления команды перехода.
Надо учесть еще следующее, так как на шаге декодирования команды адрес перехода еще не известе, то снаяала генерируется команда jle +0, а при втором проходе транслятора она уже заменяется на jle +5. Делается это путем ведения списков меток и ассоцирования их с реальным адресом, естественно, что на втором проходе это смещение уже известно. Это конечно когда команда указывается как jle label, если же команда указывается как jle смещение то необходимости в расчете нет, это уже сделал программист, учитывая выше описанное.
← →
Юрий Зотов (2003-07-29 23:11) [53]> VD602 (29.07.03 14:54)
В ту же тему. Помните, когда мы на MK смотрели команду БП, то было сказано, что в режиме Авт надо набирать адрес, на единицу меньший того, куда мы хотим перейти. И было добавлено "вопрос для особо умных, дотошных и внимательных - почему так?".
Сопоставьте это с тем, что Вы обнаружили в окне CPU.
← →
Daniel (2003-07-29 23:56) [54]По поводу задания про FPU - если необходимо вычислить эпсилон при назных значениях битов Precision Control, то все в порядке, учтено :)) Кстати, в FPU-window очень удобно показаны 8-й и 9-й управляющего слова - общим десятичным числом!
Кстати, Юрий, расскажите все-же про отображение адресации со смещением в CPU-window (у вас относительно начала процедуры, у меня - относительно текущей команды). В настройках покопался достаточно основательно. Не нашел. У меня Delphi 6.
← →
Yanis (2003-07-30 03:07) [55]МОЖЕТ КТО НИБУДЬ, ЕСЛИ ПРОЧИТАЕТЕ ЭТО СООБЩЕНИЕ, ТО У МЕН БОЛЬШАЯЯ ПРОСЬБА: ПРИШЛИТЕ ПОЖАЛУЙСТА НА МЫЛО АРХИВ ВСЕХ ЭТАПОВ(1-5). ПОЖАЛУЙСТА. СПАСИБО.
← →
Юрий Зотов (2003-07-30 09:22) [56]> Yanis © (30.07.03 03:07)
Ссылка работает: http://www.baseprogram.narod.ru
Просто сохраните с нее страницы для автономного просмотра.
← →
Maks Realov (2003-07-30 10:48) [57]Здравствуйте.
Недавно стал проходить Этапы.
Возник вопрос, который до конца не могу понять:
почему, если в 16-ти ричной системе 1 - это 0001 в двоичной, а 3 - это 0011, то число 13 в 16-ти ричной системе равно числу в шеснадцатирично-двоичной системе, т.е. 10011 (если перевести это число опять в 16-ричную систему, мы получим 13).
В свою очередь, в 10-ой системе 1 <=> 1 в двоичной, 3 - 11 в двоичной. А число 13 представленное в десятично-двоичной как представить? Сколько разрядов должно быть? Ведь не запишеш же 10011 - это не верно.
Я так понял, что прямой перевод из 16-ричной в 2-ую возможен потому что основание 16-ой системы кратно двум в степени (в данном случае 4).
Вопрос: из каких систем возможно прямое преобразование в 2-ую. (из тех, у которых основание кратно 2^n ?)
← →
AlexRush (2003-07-30 11:01) [58]2Юрий Зотов © Взломать защиту, упирающуюся в jz/jnz - это весьма полезно для начинающих программистов (да и для некоторых неначинающих тоже ;). По крайней мере люди начинают понимать, как НЕ надо защищать свою программу.
Почему бы не пойти дальше, и не предложить некоторые "усожненные" способы защиты своих прог от, скажем так, "advansed user" и тех, кто научился искать jz/jnz.
Что скажете ?
← →
AlexRush (2003-07-30 11:27) [59]Наконец-то сподобился прсмотреть предыдущие этапы...
2Юрий Зотов ©:
Мне не совсем понятна концепция Ваших уроков. Знания и навыки работы с разными системы исчисления - безусловно необходимы для любого программиста. Особенно полезно "тыкать носом" в это начинающих, ибо часто они (по себе помню :) сразу начинают Web-сервера писать, не зная , что такое "Access Violation at address 0x400FFEBC". (Здесь же и базовые знания поцессора и архитектуры ПК пригодятся).
Но (может быть я недоглядел ?) где такие основополагающие вещи, как структуры данных, конструкции ветвления, циклов и пр. ?
Я сам лично наблюдал картину, когда в курсе MFC народу пытались объяснить, что такое очередь собщений... Но только не учли тот факт, что что такое очередь, этому самому народу никто не рассказывал...
← →
Юрий Зотов (2003-07-30 11:32) [60]> AlexRush © (30.07.03 11:01)
Всему свое время. Все же цель курса не в том, чтобы рассказать о каких-то конкретных технологиях (взлома, защиты, еще чего-то), а в том, чтобы растолковать людям базу (эх, где они сейчас, старые книги!) и научить их понимать, что они пишут и как оно работает. После чего эти люди уже перестанут быть начинающими и начнут нормально писать, думая уже не о кодинге, а об алгоритме. И читать им нужно будет уже не Архангельского, а Кнута. Это - качественно другой уровень, он и есть цель.
Все примеры и задания подчинены этому же глобальному направлению. В том числе, и задание со "взломом" собственной программы. Целью ведь ставился не сам взлом, важно было, чтобы человек пощупал машинный код "ручками", сопоставил его с кодом на Паскале и понял, что такое переходы и с чем их едят. И преследовалась еще одна цель - подвести к адресации. Судя по вопросам - получилось. По крайней мере, у тех, кто этого хотел.
Если же для раскрытия какой-то темы потребуются примеры продвинутых защит или взломов - они будут использованы, без всяких колебаний. Но не как самоцель.
> Maks Realov (30.07.03 10:48)
Не совсем понятна суть проблемы, постарайтесь сформулировать ее более четко. Возможно, это будет проще, если не писать ведущих нулей - иначе возникает путаница самого числа (как понятия арифметики) и его внутреннего представления в машине.
А по вопросу - да, прямой перевод в двоичную систему возможен из систем с основанием, кратным степени двойки: четверичной, восьмиричной, шестнадцатиричной и т.д. Для этого просто каждая цифра записывается в ее двоичном виде. А для обратного перевода двоичная запись разбивается на пары (триады, тетрады...) и каждая пара (триада, татерада...) записывается в виде одной цифры.
← →
AlexRush (2003-07-30 11:52) [61]2Юрий Зотов © (30.07.03 11:32)
> где они сейчас, старые книги! - в библиотеке (у нас на четвертом этаже :) Вот только большинство молодых пользователей инэта не знает, что книги еще и на бумаге печатают :(
Теперь я представляю себе задачу Ваших веток, как направляющих на путь истинный.
P.S. И все же, Юрий, я ожидал Ваших коментариев по поводу http://delphimaster.net/view/14-1046809017/
P.S./2 Мне кажется, Вашим ученикам могли бы быть полезны эти небольшие исследования. (IMHO)
← →
Maks Realov (2003-07-30 12:21) [62]Юрий,
при обратном переводе в двоичную - кол-во разрядов в паре равно степени двойки - правильно?
А проблема, была такая: почему из 16-ой системы можно "напрямую" переводить число в 2-ую, а из 10-ой напрямую в 2-ую нельза?
Ответ: потому что основание 10-ой системы не кратно 2^n.
- это понятно, но математическое обоснование данного правило не очевидно :(
Спасибо за Этапы.
← →
Aldor (2003-07-30 12:23) [63]2 Maks Realov:
Действительно, перевести из системы с основанием 2^n в двоичную и обратно очень просто:
Например, если n = 4, т.е. шестнадцатиричная система, то просто разбивай двоичное число на тетрады (четыре(n) разряда) и подставляй 16-ричные эквиваленты и наоборот:
1110100100101 = 0001 1101 0010 0101 = $1D25
1 D 2 ( триады) 2 Maks Realov:
Действительно, перевести из системы с основанием 2^n в двоичную и обратно очень просто:
Например, если n = 4, т.е. шестнадцатиричная система, то просто разбивай двоичное число на тетрады (четыре(n) разряда) и подставляй 16-ричные эквиваленты и наоборот:
1110100100101 = 0001 1101 0010 0101 = $1D25
1 D 2 5
Всё! Обратоно то же самое. Далее если система восьмиричная, то разбиваем на тройки (триады), так как 8 = 2^3.
Это очень простое свойство и легко доказывается даже для общего случая систем счисления с основанием k^n.
← →
Aldor (2003-07-30 13:37) [64]В предыдущую:
Жалко сместилось, цифры 1 D 2 5 считать стоящими под соответствующими тетрадами
← →
Bel (2003-07-30 14:44) [65]> Maks Realov (30.07.03 12:21)
> А проблема, была такая: почему из 16-ой системы можно "напрямую" переводить число в 2-ую, а из 10-ой напрямую в 2-ую нельза?
> Ответ: потому что основание 10-ой системы не кратно 2^n.
> - это понятно, но математическое обоснование данного правило не очевидно :(
Вот тебе краткое обоснование:
Напишем числа в разных системах счисления, прибавляя каждый раз по единице:
10-чн. 2-чн. 16-чн.
00 0000 00
01 0001 01
02 0010 02
03 0011 03
04 0100 04
05 0101 05
06 0110 06
07 0111 07
08 1000 08
09 1001 09
10 1010 0A
11 1011 0B
12 1100 0C
13 1101 0D
14 1110 0E
15 1111 0F
16 10000 10
17 10001 ( соответственно, 5-го и 2-го)> Maks Realov (30.07.03 12:21)
> А проблема, была такая: почему из 16-ой системы можно "напрямую" переводить число в 2-ую, а из 10-ой напрямую в 2-ую нельза?
> Ответ: потому что основание 10-ой системы не кратно 2^n.
> - это понятно, но математическое обоснование данного правило не очевидно :(
Вот тебе краткое обоснование:
Напишем числа в разных системах счисления, прибавляя каждый раз по единице:
10-чн. 2-чн. 16-чн.
00 0000 00
01 0001 01
02 0010 02
03 0011 03
04 0100 04
05 0101 05
06 0110 06
07 0111 07
08 1000 08
09 1001 09
10 1010 0A
11 1011 0B
12 1100 0C
13 1101 0D
14 1110 0E
15 1111 0F
16 10000 10
17 10001 11
Обрати внимание, при переходе к числу 16 у двоичного и 16-чного числа происходит увеличение старшего (соответственно, 5-го и 2-го) разряда на единицу, в то время, как у 10-чного это происходит раньше. И так будет постоянно - каждый перенос единицы из младшего разряда в старший в 16-чн. числе будет совпадать с переносом единицы из 4-го разряда в 5-й (8->9, 12->13 и т.д.) в 2-чном числе. Можешь попробовать продолжить ряд.
Количество всех состояний одного разряда 16-чного числа равно количеству состояний 4-разрядного 2-чного числа (=16), ни больше, ни меньше. Именно поэтому легко переводить числа из 2-чн. системы в 16-чн. и обратно.
Для 10-чн. системы такого соответствия нет.
Существует ещё такое понятие, как двоично-десятичная система - когда каждая 10-чн. цифра записывается 4-разрядным 2-чн. числом. Не знаю, применяется ли она сейчас где-либо. В институте мы, помню, даже делали схему для двоично-десятичной коррекции.
← →
хм (2003-07-30 14:44) [66]>Жалко сместилось, цифры 1 D 2 5 считать стоящими под >соответствующими тетрадами
Используй тег code
← →
keymaster (2003-07-30 16:09) [67]А может всё это (все разделы для начинающих) выложить в "статьи"?
Т.К. в форумах они рано или поздно попадут в архивы и найти их станет проблемно.
← →
VD602 (2003-07-30 17:16) [68]http://delphimaster.net/view/14-1046809017/
← →
VD602 (2003-07-31 00:42) [69]Удалено модератором
← →
VD602 (2003-07-31 12:22) [70]Удалено модератором
← →
Daniel (2003-07-31 16:30) [71]А я еще одну классную фичу CPU-window обнаружил: оказывается, в строке запроса "Goto address" можно написать просто EBP и сразу попадаешь в область, где хранятся все твои переменные. Вот.
Юрий, когда планируете следующий этап?
Дайте что-ль пока задание какое-нить.
← →
Daniel (2003-07-31 17:01) [72]Есть одна проблемка с размещением в памяти - если порядок байт инвертирован, то порядок бит в байте инвертирован или нет?
Вот я пишу
A := $4321;
Ожидаемо, что в памяти запишется (при по-байтовом выводе)
12 34
(начиная с младшего байта)
На деле имеем:21 43
Я вот что думаю: все дело в отображении содержимого памяти ЦПУ-окном: содержимое выбранной еденицы отображения (байт, слово, длинное слово) отображается в привычном виде, начиная со старшего байта, а порядок этих единиц - реальный, т.е.
массив в пямяти располагается с МЛАДШЕГО элемента.
И если бы в ЦПУ-окне отображались бы биты, то мы увидели бы реальное "положение дел", а так мы видим биты в инвертированном, но привычном порядке и возникает вышеописанная ситуация. На самом деле в пямяти:
1 2 3 4
0001 0010 0011 0100
А вот после помещения этого слова в регистр, все становится в привычином виде: $4321
Прав ли я?
← →
AlexRush (2003-07-31 17:03) [73]>порядок бит в байте инвертирован или нет? - нет.
>А вот после помещения этого слова в регистр, все становится в >привычином виде: $4321
> Прав ли я? - да
← →
Юрий Зотов (2003-07-31 17:11) [74]> Daniel (31.07.03 17:01)
1. Биты не инвертируются. Инвертируются 2-х байтовые слова, а внутри них - байты. И в памяти, и в регистрах.
2. $4321 - это 2-х байтовое число, а не 4-х. Естественно, оно хранится, как $2143.
3. Как хранятся массивы - это уже вопрос к компилятору. Как он скомпилирует адресацию элементов - так и будет. Об этом - на следующем этапе.
← →
Anatoly Podgoretsky (2003-07-31 17:14) [75]Daniel (31.07.03 17:01)
Порядок байт не инвертирован, младшии байты по младшим адресам, старшие по старшим адресам. У машин фирмы IBM порядок байт инветирован, кроме того у них математика не с дополнением до двух, а с дополнением до единицы. ТО что ты привел это символьное представление числа в виде шестнадцатиричного, типа слово. При символьной записи мы пишем старшие разряды слева, для памяти же нет понятия слева/справа. Аналогично с битами, мы можем писать как нам угодно (обычно старшие справа, но так не всегда), но в памяти они опять же по тому же принципу - младшии биты в младших разрядах, а старшии в старших.
Вот так при указанной тобой системе наблюдения не получится, будет побайтовая запись, но тогда ее не надо рассмтривать как слово, а как два байта, по младшему адресу находится байт 21, а по станшему байт 43, если же рассматривать как слово то по адресу будет расположено слово со значение 4321Б ещи интереснее если ты будешь рассматривать двойное слово, такое как $87654321, то по байтно, будет четыре байта 21 43 65 87, по словно, будет два слова 4321 и 8765 и как двойное слово - одно равное 87654321
По регистрам точно также, если как слово, то 4321, если как пара регистров, то 21 и 43, хоть слева направо, хоть сверху вниз, в общем в любом направлении.
← →
AlexRush (2003-07-31 18:09) [76]2 Юрий Зотов © (31.07.03 17:11) Вы меня упорно игнорируете... а я настойчивый.... 8\
← →
Юрий Зотов (2003-07-31 18:40) [77]> AlexRush © (31.07.03 18:09)
Да при чем тут игнормрование? Ну Вы поймите, там же надо серьезно и долго сидеть и разбираться, что к чему. Вам было интересно - Вы это сделали. Не скажу, что тема мне неинтересна, но, видимо, гораздо меньше, чем Вам (а что тут особенного? ничего), вот поэтому она все время и отходит на второй план.
← →
AlexRush (2003-07-31 18:50) [78]2Юрий Зотов © (31.07.03 18:40)
> вот поэтому она все время и отходит на второй план. - отходит она на второй план по другим причинам. Мало кто из здешних завсегдатаев имеет представление о той теме вобще.
О своей назойливости:
смею напомнить: Юрий Зотов © (28.07.03 15:19) Давайте поднимем, действительно интересно. Может, и я че умное вякну, а уж других-то наверняка послушаю с удовольствием.
- ввиду чего я расчитывал на Ваш ответ на конкретный вопрос по поводу CASE...OF.
← →
Best Gun (2003-07-31 22:48) [79]AlexRush, ну отстань от человека, а? Тебе уже все обьяснили. Внимание привлек - и хорошо. Не надо флудить в этой ветке - она не для того создана
← →
Юрий Зотов (2003-08-01 00:23) [80]Ну почему обязательно "отстань"? Тема действительно очень интересная, но о ней нельзя говорить просто так, "с кондачка", это не та тема, не для "ля-ля-тополя".
Александр, Вы же прекрасно понимаете, что в вопросах генерации кода вообще мало кто по-настоящему глубоко разбирается. Тем более, прикладники-самоучки, коих здесь большинство. Это же не специализированный форум по проблемам разработки компиляторов. Даже и во всем мире, думаю, наберется не так уж много народа, писавшего серьезные промышленные компиляторы - тем более, блок генерации, да еще с оптимизацией.
Что касается меня, то я писал синтаксические и лексические анализаторы, интерпретаторы, и даже свой язык имеется. Но о генерации кода и его оптимизации только читал, самому писать не приходилось. Да и читал-то уже довольно давно.
Поэтому давайте так. Стоит у меня знаменитая "книга дракона", ну и еще кое-что есть. Посмотрю еще раз о генерации, надо освежить. Может, тогда и пойму, почему Паскалевский CASE требует константы и что там за дела с таблицей переходов. Тогда и отвечу. А сейчас - ну что я могу сказать? Только одно - а шут его знает, почему Borland написала именно так а не иначе. Кто писал - у того и спрашивать надо.
← →
AlexRush (2003-08-01 12:18) [81]2Юрий Зотов © (01.08.03 00:23) - Спасибо. Я трансляторов/компиляторов никогда не писал и даже теории не знаю на эту тему. Потому и спросил. Меня интересовало не столько обсуждение прелестей/недостатков dcc32, сколько ответ на конкретный вопрос.
Кстати, если Вас не затруднит, поделитесь линками хорошую на литературу по теме. С удовольствием поинтересуюсь.
P.S. Практика показала, что на данном форуме тема нежизнеспособна. Пожалуй стоит прекратить ее обсуждение.
P.P.S 2Best Gun (31.07.03 22:48) - а обсасывание чужих мировозрений на программерском форуме - не флуд ??
← →
VEG (2003-08-02 12:31) [82]Удалено модератором
← →
Malder (2003-08-04 11:37) [83]Юрий, вам письмо. Надо решить насчет сайта
← →
Kair (2003-08-04 20:25) [84]"Сломал".
Только вот какой вопрос:
В Дельфи это jnz, а в дизассемблере это jne.
Почему?
← →
onix (2003-08-05 11:46) [85]"Сломал".
Это оказалось совсем не так просто.
Пробовал повторить как Daniel, но ничего не получилось.
Хотя нашел то что нужно по этой же схеме. Но остались некоторые неясности. Переписал код так:
procedure TForm1.FormCreate(Sender: TObject);
begin
showmessage("first message");
if Sender = Self then Halt;
showmessage("second message");
end;
Нашел "first message" и "second message", наивно полагая что искомай код окажется между ними, но оказалось не так. Он был
выше. ПОЧЕМУ?
← →
AlexRush (2003-08-05 13:44) [86]2Kair © (04.08.03 20:25) JNE - это второе название JNZ. Одно и то же.
← →
VEG (2003-08-05 19:16) [87]Up!
Спасибо за старания!!!
Жду этап 6!!!
← →
VD602 (2003-08-05 23:16) [88]Юрий, жил, Юрий ЖИВ, Юрий будет жить! Вы не представляете, как я рад, что вы все-таки живы!
← →
Юрий Зотов (2003-08-06 06:54) [89]> VD602 (05.08.03 23:16)
А уж я-то как рад, Вы даже не представляете...
:о)
Вообще, даже интересно было, хотя и жутковато немного. Думаю, в мире не так уж много людей, которым удалось как бы "побывать" на собственных похоронах. Одно плохо - если все-таки это было совпадение, а не шутка.
Этап готовлю, но раньше следующей недели выкладывать точно не буду. Потому что возможны новости, жду их.
← →
AZ (2003-08-06 07:02) [90]С воскресением!
← →
iNew (2003-08-06 07:34) [91]> Юрий Зотов
У вас случайно не сохранились пердыдущие 4 этапа с этого форума?
Если да то можно ссылочку или на мыло.
← →
Юрий Зотов (2003-08-06 07:46) [92]> iNew © (06.08.03 07:34)
http://www.baseprogram.narod.ru
← →
iNew (2003-08-06 08:33) [93]> Юрий Зотов
Спасибо.
← →
VD602 (2003-08-06 11:20) [94]Юрий Зотов © (06.08.03 06:54)
> возможны новости, жду их.
Какие новости? "Юрий Зотов родился", "Юрий Зотов забеременел" :)
После "смерти" куда уж дальше? :)))))
Или вы про появление 64-разрядгых процесссоров?
← →
blackman (2003-08-06 12:24) [95]>VD602
Совпадений бывает довольно много
http://lenta.chaspik.spb.ru/cgi-bin/index.cgi?date=17&month=05&year=2001&rub=6&stat=1
что однако не означает причастности к ним Юрий Зотов ©
← →
Malder (2003-08-06 12:34) [96]Юрий, извините. Но вы собираетесь почтовый ящик проверять? Или скажите истинный почтовый адрес, где можно достучаться ;)
← →
race1 (2003-08-06 14:06) [97]>Malder © (06.08.03 12:34)
И мне бы интересно узнать название вашего мыла ;) для делового предложения
← →
Lamers klan (2003-08-07 16:00) [98]Юрий, большое спасибо Вам за Этапы.
Нас много и мы надеемся на продолжение.
Не бросайте нас!!!
← →
snoup (2003-08-07 16:34) [99]UP! Когда по идеи должен появиться эпат 6? Юрию Зотову, спасибо, очень увлекательно и главное ПОЛЕЗНО!!!.
← →
Malder (2003-08-08 13:13) [100]race1, твое письмо я получил, по этому поводу и хочу достучаться до Юрия.
← →
DeMoN-777 (2003-08-08 14:35) [101]>to all
Уважаемые, с всязи с поломкой винчестера прошу Вас прислать мне на почту полные ветки сей "дискуссии" начиная с этапов 1-4. Появилось немного св. времени, сегодня вечером начну делать сайт с возможностью интерактива. НУЖНЫ полные версии предыдущих веток. Если таковые имеются, милости прошу на alekseev@freemail.ru
← →
Malder (2003-08-08 17:33) [102]DeMoN-777, ну ты прям как маленький. Собрался делать сайт, а даже ЭТОТ топик прочесть НИКАК не можешь.
www.baseprogram.narod.ru
сколько можно?
← →
Malder (2003-08-08 17:40) [103]Блин, а Зотов вообще здесь бывает? Может, он куда отдыхать уехал? Никто не в курсе?
← →
DeMoN-777 (2003-08-08 19:37) [104]
> Malder © (08.08.03 17:33)
> DeMoN-777, ну ты прям как маленький. Собрался делать сайт,
> а даже ЭТОТ топик прочесть НИКАК не можешь.
Кто ещё из нас невнимателен...!
ЗЫ ВНИМАТЕЛЬНО ПРОЧИТАЙ МОЙ ПОСТDeMoN-777 © (08.08.03 14:35)
← →
DeMoN-777 (2003-08-08 19:40) [105]>Malder © (08.08.03 17:40)
Извини брателло.. не заметил этой мизерной ссылочки.
Этот сайт создан по материалам конференций "Мастера Delphi".
Всё ОК.
← →
DeMoN-777 (2003-08-10 05:49) [106]Товарищи. Начал делать сайт. Предложите структуру, которую Вы хотели бы видеть на нём. Дабы не засорять сей топик все пожелания и предложения высылайте на почту alekseev@freemail.ru
← →
Anatoly Podgoretsky (2003-08-10 11:44) [107]А сайт чему посвящен, в данной ветке нет об этом информации.
← →
DeMoN-777 (2003-08-10 13:09) [108]>Anatoly Podgoretsky © (10.08.03 11:44)
Раз в этом топике, то урокам Ю.З соответственно.
← →
Anatoly Podgoretsky (2003-08-10 13:22) [109]Понятно, просто попутно в других ветках обсуждаются и другие предложения. Насколько я знаю есть и другие сайты содержащие уроки ЮЗ, ты пробовал с ними связываться, по поводу объединения усилий.
← →
DeMoN-777 (2003-08-10 13:38) [110]>Anatoly Podgoretsky © (10.08.03 13:22)
Я знаю только сайт Marser-а на народе. Попробую с ним связвться. Дизайн почти готов, осталось сделать динамику и навигацию.
ЗЫ
Все кто может чем либо помочь, обращайтесь.
← →
Malder (2003-08-10 22:10) [111]А какой сайт Марсера?
Я знаю на народе только свой сайт www.baseprogram.narod.ru :)
← →
DeMoN-777 (2003-08-10 22:19) [112]Malder © (10.08.03 22:10)
Сорри, попутался =) Напиши мне письмо, чтоб с тобой связаться можно было.
← →
Marser (2003-08-10 22:41) [113]Теперь понятно, о чем ты со мной заговаривал %-) У меня всего один сайт, да и тот глубоко в разработке, да и тот о Тридцатилетней войне(всегда повторял - нельзя циклиться на программинге). Ещё есть сабжевый сайт Lipsky, но там всего два этапа.
← →
Malder (2003-08-10 22:55) [114]DeMoN-777, Хочешь - сам пищи мне письмо. Реквизиты на сайте
← →
xmm (2003-08-12 01:42) [115]up
← →
vidiv (2003-08-12 02:47) [116]^
← →
snoup (2003-08-12 11:18) [117]Уважаемый Юрий Зотов, вы нас покинули?
← →
snoup (2003-08-12 11:20) [118]Уважаемый Юрий Зотов, вы нас покинули?
← →
Camus (2003-08-12 11:27) [119]> snoup © (12.08.03 11:20) [118]
Не покинул. Мне это ТОЧНО известно. Об остальном ЮЗ скажет сам, через некоторое время.
:о)
← →
Yakudza (2003-08-13 16:36) [120]Даааа, 5 этап уже, что-то я пролунил все движение, прийдеться нагонять :)
← →
snoup (2003-08-15 15:52) [121]АП!
← →
snoup (2003-08-16 11:21) [122]UP! Мдда...
← →
Юрий Зотов (2003-08-16 12:37) [123]> snoup © (16.08.03 11:21) [122]
Спокойнее. Проект не загнулся. Даже наоборот. Просто идет его организация.
← →
Омлет (2003-08-16 13:40) [124]Дай собаке палец - руку откусит.
← →
Malder (2003-08-16 15:22) [125]Юрий, я не очень понимаю ваше игнорирование.
← →
Юрий Зотов (2003-08-16 19:03) [126]> Malder © (16.08.03 15:22) [125]
Да нет никакого игнорирования. Просто пока еще не все ясно, поэтому и сказать конкретно пока нечего. Будет ясно - скажу, конечно.
← →
snoup (2003-08-17 14:15) [127]>Юрий Зотов Спасибо
← →
Malder (2003-08-17 17:34) [128]Юрий Зотов © (16.08.03 19:03) [126]
я вам письмо отправил вообще-то. Получили?
третий раз спрашиваю
← →
snoup (2003-08-20 14:10) [129]UP!
← →
snoup (2003-08-23 18:17) [130]UP! ветка скоро будет в архивах:(((
← →
Calm (2003-08-23 20:30) [131]
> ветка скоро будет в архивах:(((
Не должна. Поддержим!
← →
Igor__ (2003-08-24 00:21) [132]У меня в задании со взломом вместо 75 05 - 75 07 и соответсвенно 74 05 - 74 07.
??????
← →
Maks Realov (2003-08-26 17:42) [133]up
← →
Maks Realov (2003-08-26 17:45) [134]терпеливо жду шестого этапа, перечитывая пять предыдущих
← →
Совет (2003-08-26 17:49) [135]Ты программы пиши, а не уроки жди.
← →
blackman (2003-08-28 16:46) [136]>Юрий Зотов
Я написал вам письмо. Возможно и не дошло (сомневаюсь в адресе)
Посмотрите вот эту ссылочку:
http://blackman.wp-club.net/forums/
и если согласны на участие в проекте форума "Статьи для начинающих", то прошу вас связаться с Anatoly Podgoretsky или со мной.
← →
snoup (2003-09-08 21:08) [137]UP! Перец, пришел нашим урокам:(((
← →
Юрий Зотов (2003-09-09 00:31) [138]> snoup © (08.09.03 21:08) [137]
Никаких перцев никуда не пришло. Все идет нормально. Скоро будут новости.
← →
McSimm (2003-09-15 12:28) [139]
> Юрий Зотов ©
Юрий, у тебя почтовый адрес не изменился?
Не могу никак связаться. Свяжись пожалуйста со мной.
---
Извиняюсь за личное обращение.
← →
Dilezzz (2003-09-16 00:21) [140]А у него фишка такая - на письма не отвечать, видимо :))!
← →
NeyroSpace (2003-09-16 01:53) [141]1. Юрий Зотов молодец! Вам бы батенька за диссертацию сесть :-)(всмысле книжку для всех нас написать).
А то бестолковых книг для батонобросателей много, а тем, например, кто с асм"мом знаком очень трудно свести два пальца в темноте и понять как батоны описываются на асм"е.
В замен 20 баранов, холодильник Розелефт (финский, хороший), почетная грамота :-).
2.
>Daniel (29.07.03 19:45) [49]
Пол года отсутствовал поэтому не знаю объясняли ли что такое BIG-ENDIAN и LITTLE-ENDIAN. Судя по тому что у народа есть вопросы все-таки дополнительно поясню:
>Anatoly Podgoretsky © (31.07.03 17:14) [75]
Очень доходчиво сказал.
Разные процессоры в зависимости от конструкции представляют числа в одном из 2х порядков байт:
big-endian или little-endian.
Intel x86 хранит в памяти числа следуя от менее значимого к более значимому байту (little-endian), т.е. младшие БАЙТЫ числа занимают младшие адреса в памяти, а, например, мой любимый Z80 big-endian. Но не только Spectrum! Так же стандарты интернета требуют, чтобы передача байт по сети шла в big-endian, это также называют сетевым порядком (network-byte order).
Это еще сыграет свою роль, когда дело дойдет до обсуждения Sockets (Надеюсь дойдет :-). Вот тогда мы всех и поломаем (шучу:-)).
3. Товарищи сайтостроители! Не вижу значка ©! Упрут ведь, с руками оторвут еще до издания книги :-).
4. А где собственно герой дня с цветами, девочками и калькуляторами ??? Что случилось с великим Николаем Быковым? И создан ли чудо-калькулятор? Фирма его процветает?
← →
Pat (2003-09-18 18:43) [142]Внесу и свои пять копеек в процесс обучения :-)) Есть возможность достать эмулятор МП х8085. Если интересно, дайте знать.
P.S. Эмулятор старый под ДОС. Окна - регистры, стек, память.
← →
Pat (2003-09-18 19:20) [143]А вообще-то http://bbs.ru/cgi-bin/bbs2html?pub/msdos/debug :-))
Страницы: 1 2 3 4 вся ветка
Форум: "Потрепаться";
Текущий архив: 2003.10.06;
Скачать: [xml.tar.bz2];
Память: 0.9 MB
Время: 0.014 c