mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 15:47:53 +02:00
+ added an i8086 asm optimized strpcopy routine
git-svn-id: trunk@31915 -
This commit is contained in:
parent
3afc18f277
commit
7fb2418287
@ -15,3 +15,50 @@
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
|
||||
{$ifndef FPC_UNIT_HAS_STRPCOPY}
|
||||
{$define FPC_UNIT_HAS_STRPCOPY}
|
||||
function strpcopy(d : pchar;const s : string) : pchar;assembler;nostackframe;
|
||||
const
|
||||
{ used for an offset fixup for accessing the proc parameters in asm routines
|
||||
that use nostackframe. We can't use the parameter name directly, because
|
||||
i8086 doesn't support sp relative addressing. }
|
||||
{$ifdef FPC_X86_CODE_FAR}
|
||||
extra_param_offset = 2;
|
||||
{$else FPC_X86_CODE_FAR}
|
||||
extra_param_offset = 0;
|
||||
{$endif FPC_X86_CODE_FAR}
|
||||
asm
|
||||
mov bx, sp
|
||||
mov dx, ds // for far data models, backup ds; for near data models, use to initialize es
|
||||
{$ifdef FPC_X86_DATA_NEAR}
|
||||
mov es, dx
|
||||
mov si, ss:[bx + 4 + extra_param_offset] // @d
|
||||
mov di, ss:[bx + 2 + extra_param_offset] // @s
|
||||
{$else FPC_X86_DATA_NEAR}
|
||||
lds si, ss:[bx + 6 + extra_param_offset] // @d
|
||||
les di, ss:[bx + 2 + extra_param_offset] // @s
|
||||
{$endif FPC_X86_DATA_NEAR}
|
||||
// we will no longer use bx for reading parameters, so save di there
|
||||
// in order to be able to return it in the end
|
||||
mov bx, di
|
||||
|
||||
{$ifdef FPC_ENABLED_CLD}
|
||||
cld
|
||||
{$endif FPC_ENABLED_CLD}
|
||||
lodsb // load length in al
|
||||
xor ah, ah
|
||||
xchg cx, ax // 1 byte shorter than mov
|
||||
shr cx, 1
|
||||
rep movsw
|
||||
adc cx, cx
|
||||
rep movsb
|
||||
xchg ax, cx // ax := 0 (1 byte shorter than xor al, al)
|
||||
stosb // zero terminate the destination string
|
||||
{$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
|
||||
mov ds, dx
|
||||
mov dx, es // return segment of d in dx
|
||||
{$endif}
|
||||
xchg ax, bx // return original offset of d in ax
|
||||
end;
|
||||
{$endif FPC_UNIT_HAS_STRPCOPY}
|
||||
|
Loading…
Reference in New Issue
Block a user