Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2014-03

(no subject)

4 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Barracuda

Hello, guys!
Firstly, thank you for such a great project! It's very nice to use it in a study process in a school/university. And now a question :)
I have some trouble working on one of my projects, it's code is here: https://github.com/Barracuda72/PT
The problem is with function "SentenceSample" in "PT4LibIFace.pas"; there are two ways - my stupidness or mysterious behavior of FPC compiler. Code:
--------------------------------------------------------- function SentenceSample(N: integer): string; stdcall; begin

  //writeln('N = ', N);
  //SentenceSample := RuGetSentence(N);
  inc(N);

end;
---------------------------------------------
Of course, inc(N); added just to simplify disassembling. And there is disasm: ---------------------------------------------
sentencesample proc near
push ebp
mov ebp, esp
inc [ebp+0Ch]
leave
retn 8
---------------------------------------------
As you can see, procedure has only one parameter, but FPC generates code as if there are two parameters; and the main problem is that it trying to work with wrong variable (N is in ebp+08, not 0C; it's obvious and proved by debugging). The result is bad =) So, can you say, there am I wrong?
Ah, I'm using Lazarus 1.0.14 with FPC 2.6.2, Win32 build

Jonas Maebe
to Barracuda
Barracuda wrote 8 lines
--------------------------------------------------------- function SentenceSample(N: integer): string; stdcall; begin //writeln('N = ', N); //SentenceSample := RuGetSentence(N); inc(N); end; ---------------------------------------------

[snip]

Show quoted text 5 lines
--------------------------------------------- As you can see, procedure has only one parameter, but FPC generates code as if there are two parameters; and the main problem is that it trying to work with wrong variable (N is in ebp+08, not 0C; it's obvious and proved by debugging). The result is bad =) So, can you say, there am I wrong?

Ansistrings results are returned in a hidden call-by-reference parameter, so the offset should be correct.

Jonas

Sven Barth
to Barracuda: Hello, guys! Firstly, thank you for such a great project! It's very nice to use it in a…
Barracuda wrote 10 lines
Code: --------------------------------------------------------- function SentenceSample(N: integer): string; stdcall; begin //writeln('N = ', N); //SentenceSample := RuGetSentence(N); inc(N); end; --------------------------------------------- Of course, inc(N); added just to simplify disassembling. And there is disasm:

You don't need to disassemble. Just pass "-al" and the compiler will keep the generated assembler files (normally *.s).

Show quoted text 8 lines
--------------------------------------------- sentencesample proc near push ebp mov ebp, esp inc [ebp+0Ch] leave retn 8 ---------------------------------------------

If you would have used "-al" you would see this:

=== asm begin ===

.section .text.n_p$hiddenarg_$$_sentencesample$longint$$ansistring .balign 16,0x90
.globl P$HIDDENARG_$$_SENTENCESAMPLE$LONGINT$$ANSISTRING .type P$HIDDENARG_$$_SENTENCESAMPLE$LONGINT$$ANSISTRING,@function P$HIDDENARG_$$_SENTENCESAMPLE$LONGINT$$ANSISTRING: .Lc1:
# [thiddenarg.pas]
# [6] begin
pushl %ebp
.Lc3:
.Lc4:
movl %esp,%ebp
.Lc5:
# Var N located at ebp+12
# Var $result located at ebp+8
# [9] inc(N);
addl $1,12(%ebp)
# [10] end;
leave
ret $8
.Lc2:
.Le0:
.size P$HIDDENARG_$$_SENTENCESAMPLE$LONGINT$$ANSISTRING, .Le0
- P$HIDDENARG_$$_SENTENCESAMPLE$LONGINT$$ANSISTRING

=== asm end ===

Especially note the "N located at ..." and "$result located at ..." comments ;)

As you can see, procedure has only one parameter, but FPC generates

code as if there are two

parameters; and the main problem is that it trying to work with wrong

variable (N is in ebp+08,

not 0C; it's obvious and proved by debugging). The result is bad =)

Is there a specific reason/problem why you decided to look at the assembler code?

Regards,
Sven

Barracuda
to Sven Barth

OK, thanks. I've really figured that out - function should return PChar, not string. I'm writing an replacement for closed-source component (also written in Pascal), and using disassembler because of that. This component intercommunicate with two others, loadable library (on one side) written in Pascal and application (on other side) written in C#, both are closed-source. Anyway, thanks for help!