[fpc-devel] Internal jump instructions for longer conditional jumps

Florian Klämpfl florian at freepascal.org
Mon Apr 20 23:11:19 CEST 2020


Am 20.04.20 um 22:45 schrieb Martin Frb:
> On 20/04/2020 22:11, Florian Klämpfl wrote:
>> Am 20.04.20 um 16:44 schrieb Martin:
>>> FPC sometimes generates jump instructions as follows. (Not always 
>>> bound to "IF" but that is the example I found
>>> - If such jumps are within line info, they should not be at the start 
>>> of a line?
>>
>> Do you have some example code which shows this (together with the 
>> needed optimizer switches)?
> 
> I have not yet tried in a small example. I got it in the Lazarus IDE 
> from svn (with fpc 3.0.4)
> components\fpdebug\fpdbgcontroller.pas
> line 795 and following
> -gh -g -gw -godwarfsets  -gl   -dCR   -Ct -Co -Cr -Ci  -gt  -Sa  -ve -vw 
> -vn  -vi       -O-  -CX  -WC

Can you post also the relevant output of -al? It makes it easier to see 
where every assembler instruction comes from.

> 
> See the lines marked with //////////
> 
> It may be the nested "IF"
> If the inner "IF" evals false, it skips over it's "then" block. It jumps 
> " jmp +$61 " to after the "then begin end" block.
> 
> That might actually be the line, that is the "end" of the outer "then" 
> block, so that jump is skipping over the outer "else" block.
> 
> However, this jump, has the same line info as the "exit" line. Even so 
> the "exit" is in the "then" block, and this "jmp" line is outside of it.
> I checked the line info with objdump.
> 
> So I guess, having had a 2nd look, I got a better explanation.
> Technically this "jmp" would probably belong to the "end" of the outer 
> "then" block. But "end" for such blocks usually has no line info.
> 
> 
> 
> 
> 
> procedure TDbgControllerStepOutCmd.InternalContinue(AProcess: TDbgProcess;
>    AThread: TDbgThread);
> var
>    Outside: Boolean;
> begin
>    assert(FProcess=AProcess, 'TDbgControllerStepOutCmd.DoContinue: 
> FProcess=AProcess');
> 
>    if (AThread = FThread) then begin
>    if IsSteppedOut then begin
>      CheckForCallAndSetBreak;
>    end
>    else
>    if not assigned(FHiddenBreakpoint) then begin
>      if GetOutsideFrame(Outside) then begin
>        SetReturnAdressBreakpoint(AProcess, Outside);
>      end
>      else
>      if FStepCount < 12 then
>      begin
>        Inc(FStepCount);
>        if NextInstruction.IsCallInstruction or 
> NextInstruction.IsLeaveStackFrame then  // asm "call" // set break 
> before "leave" or the frame becomes unavail
>        begin
>          SetReturnAdressBreakpoint(AProcess, False);
>        end
>        else
>        if NextInstruction.IsReturnInstruction then  ///////////////// 
> LINE 817 ////////////////
>        begin
>          FStepCount := MaxInt; // Do one more single-step, and we're 
> finished.
>          FProcess.Continue(FProcess, FThread, True);
>          exit;   /////////////// LINE 821 ////////////////  here goes 
> the forwarder
>        end;
>      end
>      else
>      begin
>        // Enough with the single-stepping
>        SetReturnAdressBreakpoint(AProcess, False);
>      end;
>    end;
>    end;
> 
>    FProcess.Continue(FProcess, FThread, FHiddenBreakpoint = nil); 
> ///////////////// LINE 832 ////////////
> end;
> 
> B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:817 if 
> NextInstruction.IsReturnInstruction then  // asm "ret"
> 0000000100D93578 488B45E8                 mov rax,[rbp-$18]
> 0000000100D9357C 4883782800               cmp qword ptr [rax+$28],$00
> 0000000100D93581 7405                     jz +$05
> 0000000100D93583 E99E000000               jmp +$0000009E
> 0000000100D93588 488B45E8                 mov rax,[rbp-$18]
> ........
> 0000000100D93649 E8420E27FF               call -$00D8F1BE
> 0000000100D9364E 4889F1                   mov rcx,rsi
> 0000000100D93651 FF97E8000000             call dword ptr [rdi+$000000E8]
> 0000000100D93657 84C0                     test al,al
> 0000000100D93659 7502                     jnz +$02
> 0000000100D9365B EB61                     jmp +$61   //// 
> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
> 
> B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:819 
> FStepCount := MaxInt; // Do one more single-step, and we're finished.
> 0000000100D9365D 488B45E8                 mov rax,[rbp-$18]
> 0000000100D93661 C78088000000FFFFFF7F     mov [rax+$00000088],$7FFFFFFF
> 
> B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:820 
> FProcess.Continue(FProcess, FThread, True);
> 0000000100D9366B 488B45E8                 mov rax,[rbp-$18]
> 0000000100D9366F 4C8B6810                 mov r13,[rax+$10]
> 0000000100D93673 488B45E8                 mov rax,[rbp-$18]
> ..............................
> 0000000100D936B0 4C89E2                   mov rdx,r12
> 0000000100D936B3 4D89E8                   mov rax,r13
> 0000000100D936B6 FF9390010000             call dword ptr [rbx+$00000190]
> 
> B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:821 exit;
> 0000000100D936BC EB70                     jmp +$70   /////////// jump to 
> end of proc
> 0000000100D936BE EB13                     jmp +$13   //// 
> XXXXXXXXXXXXXXXX This is where the  jump forwards to line 832
> 
> B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:827 
> SetReturnAdressBreakpoint(AProcess, False);
> 0000000100D936C0 488B55F8                 mov rdx,[rbp-$08]
> 0000000100D936C4 488B4DE8                 mov rcx,[rbp-$18]
> 0000000100D936C8 41B800000000             mov eax,$00000000
> 0000000100D936CE E8CDF7FFFF               call -$00000833
> 
> B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:832 
> FProcess.Continue(FProcess, FThread, FHiddenBreakpoint = nil);
> 0000000100D936D3 488B45E8                 mov rax,[rbp-$18]
> 0000000100D936D7 4883784800               cmp qword ptr [rax+$48],$00
> 
> _______________________________________________
> fpc-devel maillist  -  fpc-devel at lists.freepascal.org
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



More information about the fpc-devel mailing list