ASM / Delphi - Split

I am trying to separate the two numbers 50 and 5. This is my code:

function Divide(Num1, Num2: Integer): Integer;
asm
  MOV   EAX, Num1
  CDQ
  MOV   ECX, Num2
  IDIV  ECX
  MOV   @RESULT, ECX
end;

This gives me an exception DivisionByZeroExceptionin Delphi. Can someone tell me what I am doing wrong?

+4
source share
2 answers

This is an instruction CDQ. From online help :

Converts a signed DWORD in EAX to a signed quad-core word in EDX: EAX, expanding the higher order EA bit in EDX

, Num2 , EDX, , CDQ EDX ECX, , ECX, 0. , :

function Divide(Num1, Num2: integer): integer;
asm
  MOV EAX, Num1
  MOV ECX, Num2
  CDQ
  IDIV ECX
  MOV @Result, EAX
end;
+9

, CDQ, EDX. , . , IDIV EAX, ECX.

asm. , asm, .

, , . , , , . . . register, , , , , !

, . . :

function Divide(Num1, Num2: integer): integer;
// Input: EAX: Num1, EDX: Num2
// Output: EAX: Result
asm
  MOV EAX, EAX
  MOV ECX, EDX
  CDQ
  IDIV ECX
  MOV EAX, EAX
end;

, . - .

, :

function Divide(Num1, Num2: integer): integer;
// Input: EAX: Num1, EDX: Num2
// Output: EAX: Result
asm
  MOV ECX, EDX
  CDQ
  IDIV ECX
end;

, , EAX, .


, asm - . . , . , , , , .

Result asm.


, div. asm, .

, . :

{$APPTYPE CONSOLE}

function DivideAsm(Num1, Num2: integer): integer;
// Input: EAX: Num1, EDX: Num2
// Output: EAX: Result
asm
  MOV ECX, EDX
  CDQ
  IDIV ECX
end;

function DividePas(Num1, Num2: integer): integer;
begin
  Result := Num1 div Num2;
end;

function DividePasInline(Num1, Num2: integer): integer; inline;
begin
  Result := Num1 div Num2;
end;

var
  i, j, k, l: Integer;

begin
  i := 666;
  j := 42;
  l := 0;
  inc(l, i div j);
  inc(l, DivideAsm(i, j));
  inc(l, DividePas(i, j));
  inc(l, DividePasInline(i, j));
  Writeln(l);
end.

DividePas , DivideAsm. :

0040524C 53               push ebx
0040524D 8BDA             mov ebx,edx
0040524F 8BC8             mov ecx,eax
00405251 8BC1             mov eax,ecx
00405253 99               cdq 
00405254 F7FB             idiv ebx
00405256 5B               pop ebx
00405257 C3               ret 

, DivideAsm /.

:

SO22570866.dpr.28: i := 666;
004060D7 BE9A020000       mov esi,$0000029a
SO22570866.dpr.29: j := 42;
004060DC BF2A000000       mov edi,$0000002a
SO22570866.dpr.30: l := 0;
004060E1 33DB             xor ebx,ebx
SO22570866.dpr.31: inc(l, i div j);
004060E3 8BC6             mov eax,esi
004060E5 99               cdq 
004060E6 F7FF             idiv edi
004060E8 03D8             add ebx,eax
SO22570866.dpr.32: inc(l, DivideAsm(i, j));
004060EA 8BD7             mov edx,edi
004060EC 8BC6             mov eax,esi
004060EE E851F1FFFF       call DivideAsm
004060F3 03D8             add ebx,eax
SO22570866.dpr.33: inc(l, DividePas(i, j));
004060F5 8BD7             mov edx,edi
004060F7 8BC6             mov eax,esi
004060F9 E84EF1FFFF       call DividePas
004060FE 03D8             add ebx,eax
SO22570866.dpr.34: inc(l, DividePasInline(i, j));
00406100 8BC6             mov eax,esi
00406102 99               cdq 
00406103 F7FF             idiv edi
00406105 03D8             add ebx,eax

, . ABI. MOV. , . , :

inc(l, DivideAsm(i, j));
inc(l, DividePas(i, j));
inc(l, i div j);
inc(l, DividePasInline(i, j));

:

SO22570866.dpr.33: inc(l, i div j);
004060F9 8BC6             mov eax,esi
004060FB 99               cdq 
004060FC F7FF             idiv edi
004060FE 8BC8             mov ecx,eax
00406100 03D9             add ebx,ecx
SO22570866.dpr.34: inc(l, DividePasInline(i, j));
00406102 03D9             add ebx,ecx

, ECX DividePasInline !

+8

Source: https://habr.com/ru/post/1532925/


All Articles