Copy on asm
От: NEOsniper Россия  
Дата: 24.01.07 23:03
Оценка:
В общем, есть в Паскалях такая функция
Copy(s:string; ind: integer; count: integer): string;

Возникла необходимость реализовать на асме для 8086/80286 (встроенном в Паскаль 7.0, напр.). Помогите, пожалуйста. Небольшое уточнение — пожалуйста, наглядно (т.е. без оптимизаций)
Нет предела самосовершенствованию
Re: Copy on asm
От: DarkMaster Украина http://www.bdslib.at.ua
Дата: 25.01.07 07:57
Оценка: 2 (1)
Здравствуйте, 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
WBR, Dmitry Beloshistov AKA [-=BDS=-]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.