stringss.inc 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Jonas Maebe, member of the
  4. Free Pascal development team
  5. Processor dependent part of strings.pp, not shared with
  6. sysutils unit.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. {$if defined(FPC_MM_TINY)}
  14. {$define FPC_X86_CODE_NEAR}
  15. {$define FPC_X86_DATA_NEAR}
  16. {$elseif defined(FPC_MM_SMALL)}
  17. {$define FPC_X86_CODE_NEAR}
  18. {$define FPC_X86_DATA_NEAR}
  19. {$elseif defined(FPC_MM_MEDIUM)}
  20. {$define FPC_X86_CODE_FAR}
  21. {$define FPC_X86_DATA_NEAR}
  22. {$elseif defined(FPC_MM_COMPACT)}
  23. {$define FPC_X86_CODE_NEAR}
  24. {$define FPC_X86_DATA_FAR}
  25. {$elseif defined(FPC_MM_LARGE)}
  26. {$define FPC_X86_CODE_FAR}
  27. {$define FPC_X86_DATA_FAR}
  28. {$elseif defined(FPC_MM_HUGE)}
  29. {$define FPC_X86_CODE_FAR}
  30. {$define FPC_X86_DATA_HUGE}
  31. {$else}
  32. {$fatal No memory model defined}
  33. {$endif}
  34. {$ifndef FPC_UNIT_HAS_STRPCOPY}
  35. {$define FPC_UNIT_HAS_STRPCOPY}
  36. function strpcopy(d : pchar;const s : string) : pchar;assembler;nostackframe;
  37. const
  38. { used for an offset fixup for accessing the proc parameters in asm routines
  39. that use nostackframe. We can't use the parameter name directly, because
  40. i8086 doesn't support sp relative addressing. }
  41. {$ifdef FPC_X86_CODE_FAR}
  42. extra_param_offset = 2;
  43. {$else FPC_X86_CODE_FAR}
  44. extra_param_offset = 0;
  45. {$endif FPC_X86_CODE_FAR}
  46. asm
  47. mov bx, sp
  48. mov dx, ds // for far data models, backup ds; for near data models, use to initialize es
  49. {$ifdef FPC_X86_DATA_NEAR}
  50. mov es, dx
  51. mov si, ss:[bx + 2 + extra_param_offset] // @s
  52. mov di, ss:[bx + 4 + extra_param_offset] // @d
  53. {$else FPC_X86_DATA_NEAR}
  54. lds si, ss:[bx + 2 + extra_param_offset] // @s
  55. les di, ss:[bx + 6 + extra_param_offset] // @d
  56. {$endif FPC_X86_DATA_NEAR}
  57. // we will no longer use bx for reading parameters, so save di there
  58. // in order to be able to return it in the end
  59. mov bx, di
  60. {$ifdef FPC_ENABLED_CLD}
  61. cld
  62. {$endif FPC_ENABLED_CLD}
  63. lodsb // load length in al
  64. xor ah, ah
  65. xchg cx, ax // 1 byte shorter than mov
  66. shr cx, 1
  67. rep movsw
  68. adc cx, cx
  69. rep movsb
  70. xchg ax, cx // ax := 0 (1 byte shorter than xor al, al)
  71. stosb // zero terminate the destination string
  72. {$if defined(FPC_X86_DATA_FAR) or defined(FPC_X86_DATA_HUGE)}
  73. mov ds, dx
  74. mov dx, es // return segment of d in dx
  75. {$endif}
  76. xchg ax, bx // return original offset of d in ax
  77. end;
  78. {$endif FPC_UNIT_HAS_STRPCOPY}