| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| I have a function that I am using in several places in an inner loop. The function converts an input nybble to it's ascii equivalent: Function HexNybble(b:byte):char; assembler; {thanks to Norbert Juffa} asm mov al,b cmp al,10 {if x<10, set CF=1} sbb al,69h {0-9: 96h..9Fh, A-F: A1h..A6h} das {0-9: subtr. 66h -> 30h-39h; A-F: subtr. 60h -> 41h-46h} end; The problem is, this code is (obviously) being CALL'd every time it is used, and each CALL (28 cycles) and RET (26 cycles) are adding 54 unnecessary cycles to this code. Since this is in an inner loop, and since I'm using this function in at least 200 places across modules and don't want to rewrite every single section to a small asm block, I was hoping to convert it to an inline() statement instead. I know from past experience (and the manual) that inline() code is not CALLd but rather the compiler "injects" the code directly into the binary where the "call" to that code is made, like a macro. I have only successfully converted procedures that don't take variables to inline; the manual seems to state that variables can be denoted with things like \ or < or something but I don't understand the syntax. Is it possible to convert the above 4-line assembler function into inline() code? |
|
#2
| |||
| |||
| On May 31, 12:33 pm, Jim Leonard <MobyGa...@gmail.com> wrote: > I have a function that I am using in several places in an inner loop. > The function converts an input nybble to it's ascii equivalent: > > Function HexNybble(b:byte):char; assembler; > {thanks to Norbert Juffa} > asm > mov al,b > cmp al,10 {if x<10, set CF=1} > sbb al,69h {0-9: 96h..9Fh, A-F: A1h..A6h} > das {0-9: subtr. 66h -> 30h-39h; > A-F: subtr. 60h -> 41h-46h} > end; Never mind, I disassembled a test compile in Turbo Debugger and figured out how to do it: Function HexNybble(w:word):char; inline( $58/ {pop ax} $3C/$0A/ {cmp al,0A} $1C/$69/ {sbb al,69} $2F {das} ); Inline, it's still not as tight as I'd like it; there is a PUSH AX to put the value onto the stack, then the POP AX immediately follows it :-/ But it's better than the CALL and RET, which are 5-6 times worse! Times like this that I wish Turbo Pascal had a built-in macro facility. |
|
#3
| |||
| |||
| On 2008-05-31, Jim Leonard <MobyGamer@gmail.com> wrote: > > Times like this that I wish Turbo Pascal had a built-in macro facility. Wrong wish, too easy macro facilities lead to abuse. Better have inlining of proper functions, also across units. Admitted it doesn't solve this case (assembler can't be inlined, and you can see why from the example), but it is a very powerful feature. |
|
#4
| |||
| |||
| In comp.lang.pascal.borland message <9ab68dd0-ca4a-417f-8e4c-a46560de5e0 7@d77g2000hsb.googlegroups.com>, Sat, 31 May 2008 16:06:04, Jim Leonard <MobyGamer@gmail.com> posted: > >Function HexNybble(w:word):char; >inline( > $58/ {pop ax} > $3C/$0A/ {cmp al,0A} > $1C/$69/ {sbb al,69} > $2F {das} >); > >Inline, it's still not as tight as I'd like it; there is a PUSH AX to >put the value onto the stack, then the POP AX immediately follows >it :-/ But it's better than the CALL and RET, which are 5-6 times >worse! See whether you can start with function HexNybble(const w : word) : char ; or function HexNybble(var w : word) : char ; -- (c) John Stockton, nr London UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME. <URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links; <URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> RAH Prins : c.l.p.b mFAQ; <URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ. |
|
#5
| |||
| |||
| On Jun 1, 3:54 pm, Dr J R Stockton <j...@merlyn.demon.co.uk> wrote: > >Inline, it's still not as tight as I'd like it; there is a PUSH AX to > >put the value onto the stack, then the POP AX immediately follows > >it :-/ But it's better than the CALL and RET, which are 5-6 times > >worse! > > See whether you can start with > function HexNybble(const w : word) : char ; > or function HexNybble(var w : word) : char ; Wouldn't (var w:word) just push the address of w onto the stack? That would be larger and slower (I'd still have to POP, but instead of the value I'd get a reference to the value). I'll check tonight. |
|
#6
| |||
| |||
| On Jun 2, 10:45 am, Jim Leonard <MobyGa...@gmail.com> wrote: > > See whether you can start with > > function HexNybble(const w : word) : char ; > > or function HexNybble(var w : word) : char ; > > Wouldn't (var w:word) just push the address of w onto the stack? That > would be larger and slower (I'd still have to POP, but instead of the > value I'd get a reference to the value). I'll check tonight. This turns out to be worse; the compiler generates the following for a var inline: mov di,(address of var) push ds push di ....and then the inline code. So this moves the address to the variable into DI, pushes DS, and pushes DI. This is a lot more work than just a non-var parameter, which pushes the variable itself. |
|
#7
| |||
| |||
| On Jun 1, 4:33 am, Marco van de Voort <mar...@stack.nl> wrote: > > Times like this that I wish Turbo Pascal had a built-in macro facility. > > Wrong wish, too easy macro facilities lead to abuse. Why? I *want* to abuse it :-) (I need the speed in a few places) > Better have inlining of proper functions, also across units. Admitted it > doesn't solve this case (assembler can't be inlined, and you can see why > from the example), but it is a very powerful feature. Well, a proper macro facility would eliminate the PUSH/POP behavior I just noted, so yes, I'd rather have macros. With Inline code Pascal still thinks I am writing a "normal" procedure/function... |
|
#8
| |||
| |||
| On 2008-06-02, Jim Leonard <MobyGamer@gmail.com> wrote: >> >> Wrong wish, too easy macro facilities lead to abuse. > > Why? I *want* to abuse it :-) (I need the speed in a few places) There is no difference in speed. Macro's are the "my only tool is a hammer, so make it a big and blunt one". It has the perception of powerful, but it damages the equipment too much long term. >> Better have inlining of proper functions, also across units. Admitted it >> doesn't solve this case (assembler can't be inlined, and you can see why >> from the example), but it is a very powerful feature. > > Well, a proper macro facility would eliminate the PUSH/POP behavior I > just noted, so yes, I'd rather have macros. With Inline code Pascal > still thinks I am writing a "normal" procedure/function... Not necessarily, since with inlining pascal that entire part (parameter allocation, prologue, epilogue) is governed by the compiler, and thus can be eliminated by it. |
|
#9
| |||
| |||
| On Jun 3, 3:08 am, Marco van de Voort <mar...@stack.nl> wrote: > > Why? I *want* to abuse it :-) (I need the speed in a few places) > > There is no difference in speed. Macro's are the "my only tool is a hammer, > so make it a big and blunt one". It has the perception of powerful, but it > damages the equipment too much long term. Then you'll have to explain why, since it seems like a benefit to me. > >> Better have inlining of proper functions, also across units. Admitted it > >> doesn't solve this case (assembler can't be inlined, and you can see why > >> from the example), but it is a very powerful feature. > > > Well, a proper macro facility would eliminate the PUSH/POP behavior I > > just noted, so yes, I'd rather have macros. With Inline code Pascal > > still thinks I am writing a "normal" procedure/function... > > Not necessarily, since with inlining pascal that entire part (parameter > allocation, prologue, epilogue) is governed by the compiler, and thus can be > eliminated by it. I'm thinking of macros in assembler; are you thinking of something else? For clarification, what I wish I had in TP7 is the ability to do something like this (imaginary syntax follows): Function DoSomething(inw:word):word; macro; asm mov ax,inw {do asm stuff here} end; ....and then in the source I could use it like this: {stuff #1} newvar:=DoSomething(inw); {stuff #2} ....and the compiled output would be something like: {stuff #1} mov ax,inw {do asm stuff here} mov newvar,ax {typical passing of function result to variable} {stuff #2} Why would that be "bad" or "abuse"? For very short functions/ procedures such as the "convert nybble value to ascii" function I previously posted, it would be a great big help instead of having to put inline assembler all over the source code. |
|
#10
| |||
| |||
| "Jim Leonard" <MobyGamer@gmail.com> wrote in message news:033794a2-e3a9-40e0-a392-c55697b159ec@e53g2000hsa.googlegroups.com... > On Jun 1, 3:54 pm, Dr J R Stockton <j...@merlyn.demon.co.uk> wrote: > > >Inline, it's still not as tight as I'd like it; there is a PUSH AX to > > >put the value onto the stack, then the POP AX immediately follows > > >it :-/ But it's better than the CALL and RET, which are 5-6 times > > >worse! > > > > See whether you can start with > > function HexNybble(const w : word) : char ; > > or function HexNybble(var w : word) : char ; > > Wouldn't (var w:word) just push the address of w onto the stack? Yes. > That would be larger and slower (I'd still have to POP, but instead of > the value I'd get a reference to the value). Indeed. -- Jay Jason Burgon - author of Graphic Vision http://homepage.ntlworld.com/gvision |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.