В общем, есть в Паскалях такая функция
Copy(s:string; ind: integer; count: integer): string;
Возникла необходимость реализовать на асме для 8086/80286 (встроенном в Паскаль 7.0, напр.). Помогите, пожалуйста. Небольшое уточнение — пожалуйста, наглядно (т.е. без оптимизаций)
Здравствуйте, NEOsniper, Вы писали:
NEO>В общем, есть в Паскалях такая функция
NEO>NEO>Copy(s:string; ind: integer; count: integer): string;
NEO>
NEO>Возникла необходимость реализовать на асме для 8086/80286 (встроенном в Паскаль 7.0, напр.). Помогите, пожалуйста. Небольшое уточнение — пожалуйста, наглядно (т.е. без оптимизаций)
Нашел в загашнике...
;-------------------------------------------------------------------------------
; Copy standard function: Copy (VAR S: STRING; Index, Count: INTEGER): STRING
;
; Copy copies Count characters from S, starting at position Index to a 256 byte
; temporary string buffer. If there are less than Count characters in S after
; Index, the routine copies all the characters from Index to the end of S (note
; that this number can be zero).
;
; On entry: [SP+4] Count
; [SP+6] Index
; [SP+8] Address of source string S
; [SP+12] Address of destination string
;
; On exit: [SP] Address of destination string
;-------------------------------------------------------------------------------
SCopy PROC FAR
CLD ; auto increment for string instructions
PUSH DS ; save caller's data segment
MOV BX, SP ; make new frame pointer
LES DI, SS:[BX+14] ; load pointer to destination
LDS SI, SS:[BX+10] ; load pointer to source
MOV AX, SS:[BX+6] ; get copy count
MOV BX, SS:[BX+8] ; get index
CWD ; DX = FFFF if count negative, else DX=0
NOT DX ; DX = FFFF if count positive, else DX=0
AND AX, DX ; Max (count, 0)
DEC BX ; index - 1
CMP BH, 80h ; index-1 < 0 ?
SBB DX, DX ; DX = FFFF if index-1 pos., else DX = 0
AND BX, DX ; Max (index-1, 0)
MOV CL, [SI] ; source length
INC SI ; pointer to 1st char of source
XOR CH, CH ; zero-extend source length to word
SUB BX, CX ; index - 1 - length
SBB DX, DX ; DX=0, if index-1 > length, else DX=FFFF
AND BX, DX ; - max # of chars that could be copied
NEG BX ; maxcount
SUB AX, BX ; count - maxcount
SBB DX, DX ; DX=0, if count > maxcount, else DX=FFFF
AND AX, DX ; count - maxcount = 0, if count>maxcount
ADD AX, BX ; AX = Min (Count, MaxCount)
SUB CX, BX ; CX = Min (Index-1, Length)
ADD SI, CX ; pointer to first char to copy
STOSB ; store length of result
MOV CX, AX ; need it in CX for string instruction
SHR CX, 1 ; number of chars odd ?
JNC $even_copy ; no, even
MOVSB ; move single char
$even_copy: REP MOVSW ; copy chars two at a time
POP DS ; restore caller's data segment
RET 8 ; leave destination pointer on stack
SCopy ENDP