код на Паскале: Код (Text): i:=Length(A)-1; while ((i>=0) and (A[i]=0)) do i:=i-1; A--массив (только с положительным индексом [0..i-1]), переход через 0 (i:=i-1) обрабатывается компилятором (по CF?). какой тип надо выбрать для переменной i, чтобы не зависить от компилятора - со знаком или можно без знака
Без знака переменная всегда будет иметь неотрицательное значение, соответственно i>=0 всегда будет верным.
А вы уверены что копмилятор по i:=i-1 не создаст команду DEC, которая не влияет на CF? Здесь скорее всего придется обращать внимание на SF который взведется и при использовании SUB и при использовании DEC
А Вы уверены что после операции вычитания будет условный переход, а не сравнение и только потом условный переход? При чем тут вообще что генерирует компилятор? На сколько я понял, вопрос в том, можно ли использовать в данном случае беззнаковую переменную. Ответ - нет. К слову, компилятор, наверное, должен следовать стандарту, и, какой тип не выбирай для переменной, результат исполнения должен быть одинаков для всех компиляторов, если, конечно, поведение определено однозначно. Если уж сильно хочется использовать переменную без знака, можно попробовать сделать так: Код (Text): i:=Length(A); while ((i>0) and (A[i-1]=0)) do i:=i-1; i:=i-1
Код (Text): ;delphi7 procedure TForm1.FormCreate(Sender: TObject); const a:AnsiString = 't00x'; var i:dword; begin asm hlt; end; i:=length(a); while (i>=0) and (a[i]=#0) do i:=i-1; end; ;OllyDbg 2.00.01 CPU Disasm Address Hex dump Command Comments 0044D0F4 . FFFFFFFF dd FFFFFFFF 0044D0F8 . 04000000 dd 00000004 0044D0FC . 74 30 30 78 ascii "t00x" 0044D100 00 db 00 0044D101 00 db 00 0044D102 00 db 00 0044D103 00 db 00 0044D104 F4 db F4 ; char '' 0044D105 /. A1 34ED4400 mov eax,[dword ds:Project1.44ED34] ; ASCII "t00x" 0044D10A |. E8 9173FBFF call Project1.004044A0 ; длина строки 0044D10F |. EB 01 jmp short Project1.0044D112 0044D111 |> 48 /dec eax 0044D112 |> 85C0 |test eax,eax 0044D114 |. 72 0D |jb short Project1.0044D123 ; зачем CF, или Olly нелады? 0044D116 |. 8B15 34ED4400 |mov edx,[dword ds:Project1.44ED34] ; ASCII "t00x" 0044D11C |. 807C02 FF 00 |cmp [byte ds:eax+edx-1],0 0044D121 |.^ 74 EE \je short Project1.0044D111 0044D123 \> C3 retn wasm.ru, в стиле Armicron в поле кода поправьте пж. шрифты. компилятор не додумал mov edx,offset string делать только раз, или ожидал длинного цикла
KeSqueer Ну в однгом я оказался прав, компилятор Delphi превратил i:=i-1 в dec eax, дальше идет сравнение с нулем, но не через CMP eax,0 а через TEST eax,eax. Команда TEST, как и остальные логические команды, флаг CF должна сбросить Команда OF SF ZF AF PF CF TEST 0 M M - M 0 а переход JB=JNAE=JC происходит только тогда когда СF=1, а он заведомо сброшен
t00x, если a:AnsiString, мы не можем адресовать 0й символ: while i>=0 Код (Text): ;lazarus CPU Disasm Address Hex dump Command Comments 0041D3CD /. A1 30B45300 mov eax,[dword ds:project1.53B430] ; ASCII "t00x" 0041D3D2 |. 85C0 test eax,eax 0041D3D4 |. 74 03 je short project1.0041D3D9 0041D3D6 |. 8B40 FC mov eax,[dword ds:eax-4] 0041D3D9 |> 8945 F4 mov [dword ss:ebp-0C],eax 0041D3DC |. EB 13 jmp short project1.0041D3F1 0041D3DE | 89F6 mov esi,esi 0041D3E0 |> 8B45 F4 /mov eax,[dword ss:ebp-0C] 0041D3E3 |. BA 00000000 |mov edx,0 0041D3E8 |. 83E8 01 |sub eax,1 0041D3EB |. 83DA 00 |sbb edx,0 0041D3EE |. 8945 F4 |mov [dword ss:ebp-0C],eax 0041D3F1 |> A1 30B45300 |mov eax,[dword ds:project1.53B430] ; ASCII "t00x" 0041D3F6 |. 8B55 F4 |mov edx,[dword ss:ebp-0C] 0041D3F9 |. 8A4410 FF |mov al,[byte ds:edx+eax-1] 0041D3FD |. 84C0 |test al,al 0041D3FF |.^ 74 DF \je short project1.0041D3E0 0041D401 |. C9 leave 0041D402 \. C3 retn
Покажите пожалуйста, как было бы на hll c/c++/... не от Borland. Своих сей нету. Просто интересно. Код (Text): procedure TForm1.FormCreate(Sender: TObject); const a:AnsiString = 't00x'; begin asm hlt xor edi,edi or edi,[a] jz @hll_shit std mov al,0 mov ecx,[edi-4] lea edi,[edi+ecx-1] repe scasb @hll_shit: end; end;
KeSqueer так и сделал. edemko A: Array of TMyType; Mikl___ да, FPC компилирует в TEST RAX, RAX до проверки i=0 ни разу не доходило
И поразила меня с++ила: Код (Text): #include <iostream> using namespace std; int main() { const char szMiniGW[] = "MiniGW"; asm("hlt"); for(int i = 0; szMiniGW[i] != 0; i++){ }; return 0; /* CPU Disasm Address Hex dump Command Comments 00401344 |> /8A10 /mov dl,[byte ds:eax] 00401346 |. |40 |inc eax 00401347 |. |84D2 |test dl,dl 00401349 |.^\75 F9 \jne short operators.00401344 */ } Советую посетить: -(enu)Code::Blocks IDE: http://codeblocks.org -(enu)GNU Compiler Collection manuals: http://gcc.gnu.org/onlinedocs/ -(rus)c++ for dummies(чайникс): http://books.tr200.ru/v.php?p=21&t=18&id=3073 -(enu)c++ library: http://boost.org/ -(rus)gnu compiler internals: http://goldbook.ws/2008/02/23/gcc.-polnoe-rukovodstvo.html Подскажите пожалуйста, как писать асмом в этой среде.