📄 balib.s
字号:
/* put src in %esi, dest in %edi, and count in %ecx */ movl ARG1(%ebp),%esi /* source */ movl ARG2(%ebp),%edi /* destination */ movl ARG3(%ebp),%ecx /* count */ shll $1,%ecx /* convert count to bytes */ /* Find out if there is an overlap problem. * We have to copy backwards if destination lies within source, * i.e. ((destination - source) > 0 && < nbytes) */ cld movl %edi,%eax /* destination */ subl %esi,%eax /* - source */ jle bCopyW0 /* <= 0 means copy forward */ cmpl %ecx,%eax /* compare to nbytes */ jge bCopyW0 /* >= nbytes means copy forward */ addl %ecx,%esi addl %ecx,%edi subl $2,%esi subl $2,%edi std /* Copy the whole thing, word by word */bCopyW0: shrl $1,%ecx /* convert count to words */ je bCopyW1 /* do the test first */ rep movswbCopyW1: popf popl %edi popl %esi leave ret/********************************************************************************* bcopyLongs - copy one buffer to another a long at a time** This routine copies the first `nlongs' longs from* `source' to `destination'.* It is similar to bcopy except that the copy is always performed* a long at a time. This may be desirable if one of the buffers* can only be accessed with long instructions, as in certain long-wide* memory-mapped peripherals. The source and destination must be long-aligned.** SEE ALSO: bcopy (2)** NOMANUAL - manual entry in bLib (1)* void bcopyLongs (source, destination, nlongs)* char *source; /* pointer to source buffer ** char *destination; /* pointer to destination buffer ** int nlongs; /* number of longs to copy **/ .balign 16,0x90FUNC_LABEL(bcopyLongs) pushl %ebp movl %esp,%ebp pushl %esi pushl %edi pushf /* put src in %esi, dest in %edi, and count in %ecx */ movl ARG1(%ebp),%esi /* source */ movl ARG2(%ebp),%edi /* destination */ movl ARG3(%ebp),%ecx /* count */ shll $2,%ecx /* convert count to bytes */ /* Find out if there is an overlap problem. * We have to copy backwards if destination lies within source, * i.e. ((destination - source) > 0 && < nbytes) */ cld movl %edi,%eax /* destination */ subl %esi,%eax /* - source */ jle bCopyL0 /* <= 0 means copy forward */ cmpl %ecx,%eax /* compare to nbytes */ jge bCopyL0 /* >= nbytes means copy forward */ addl %ecx,%esi addl %ecx,%edi subl $4,%esi subl $4,%edi std /* Copy the whole thing, long by long */bCopyL0: shrl $2,%ecx /* convert count to longs */ je bCopyL1 /* do the test first */ rep movslbCopyL1: popf popl %edi popl %esi leave ret/********************************************************************************* bfill - fill buffer with character** This routine fills the first `nbytes' characters of the specified buffer* with the specified character.* The fill is optimized by filling 4 bytes at a time if possible,* (see bfillBytes (2) for filling a byte at a time only).** SEE ALSO: bfillBytes (2)** NOMANUAL - manual entry in bLib (1)* void bfill (buf, nbytes, ch)* char *buf; /* pointer to buffer ** int nbytes; /* number of bytes to fill ** char ch; /* char with which to fill buffer **/ .balign 16,0x90FUNC_LABEL(bfill) pushl %ebp movl %esp,%ebp pushl %ebx pushl %edi pushf /* put buf in %edi, nbytes in %edx, and ch in %eax */ movl ARG1(%ebp),%edi /* get buf */ movl ARG2(%ebp),%edx /* nbytes */ movl ARG3(%ebp),%eax /* ch */ /* if length is less than 20, cheaper to do a byte fill */ cld cmpl $20,%edx /* test count */ jl bFill2 /* do byte fill */ /* Put ch in four bytes of %eax, so we can fill 4 bytes at a crack */ movb %al,%ah /* move ch into 2nd byte of %eax */ movzwl %ax,%ecx /* move low-word of %eax into %ecx */ shll $16,%eax /* shift ch into high-word of %eax */ orl %ecx,%eax /* or ch back into low-word of %eax */ /* If the buffer is odd-aligned, copy the first 1 - 3 byte */ movl %edi,%ebx andl $3,%ebx movl %ebx,%ecx cmpl $0,%ecx /* if long-aligned */ je bFill0 /* then goto bFill0 */ rep /* fill the 1 - 3 byte */ stosb subl %ebx,%edx /* decrement count by 1 */ /* Since we're copying 4 bytes at a crack, divide count by 4. * Keep the remainder in %edx, so we can do those bytes at the * end of the loop. */bFill0: movl %edx,%ecx shrl $2,%ecx /* count /= 4 */ je bFill1 /* do the test first */ rep stoslbFill1: andl $3,%edx /* remainder in %edx */ /* do the extras at the end */bFill2: movl %edx,%ecx cmpl $0,%ecx je bFill3 /* do the test first */ rep stosbbFill3: popf popl %edi popl %ebx leave ret/********************************************************************************* bfillBytes - fill buffer with character a byte at a time** This routine fills the first `nbytes' characters of the* specified buffer with the specified character.* It is identical to bfill (2) except that the fill is always performed* a byte at a time. This may be desirable if the buffer* can only be accessed with byte instructions, as in certain byte-wide* memory-mapped peripherals.** SEE ALSO: bfill (2)** NOMANUAL - manual entry in bLib (1)* void bfillBytes (buf, nbytes, ch)* char *buf; /* pointer to buffer ** int nbytes; /* number of bytes to fill ** char ch; /* char with which to fill buffer **/ .balign 16,0x90FUNC_LABEL(bfillBytes) pushl %ebp movl %esp,%ebp pushl %edi pushf /* put buf in %edi, nbytes in %ecx, and ch in %eax */ movl ARG1(%ebp),%edi /* get destination */ movl ARG2(%ebp),%ecx /* count */ movl ARG3(%ebp),%eax /* ch */ cmpl $0,%ecx je bFillB0 /* do the test first */ /* Copy the whole thing, byte by byte */ cld rep stosbbFillB0: popf popl %edi leave ret/********************************************************************************* bfillWords - fill buffer with specified word(2-byte) a word at a time** This routine fills the first `nwords' characters of the specified buffer* with the specified word. The fill is optimized by using the stos * instruction.* It is identical to bfill (2) except that the fill is always performed* a word at a time. This may be desirable if the buffer* can only be accessed with word instructions, as in certain 2byte-wide* memory-mapped peripherals.** SEE ALSO: bfill (2)** NOMANUAL - manual entry in bLib (1)** void bfillWords (buf, nwords, value)* char * buf; /* pointer to buffer ** int nwords; /* number of words to fill ** short value; /* short with which to fill buffer ***/ .balign 16,0x90FUNC_LABEL(bfillWords) pushl %ebp movl %esp,%ebp pushl %edi /* put buf in %edi, nlongs in %ecx, and value in %eax */ movl ARG1(%ebp),%edi /* get buf */ movl ARG2(%ebp),%ecx /* get nwords */ movl ARG3(%ebp),%eax /* get value */ cld rep stosw /* fill it, word by word */ popl %edi leave ret/********************************************************************************* bfillLongs - fill buffer with specified long(4-byte) a long at a time** This routine fills the first `nlongs' characters of the specified buffer* with the specified long. The fill is optimized by using the stos * instruction.* It is identical to bfill (2) except that the fill is always performed* a long at a time. This may be desirable if the buffer* can only be accessed with long instructions, as in certain 4byte-wide* memory-mapped peripherals.** SEE ALSO: bfill (2)** NOMANUAL - manual entry in bLib (1)** void bfillLongs (buf, nlongs, value)* char * buf; /* pointer to buffer ** int nlongs; /* number of longs to fill ** long value; /* long with which to fill buffer ***/ .balign 16,0x90FUNC_LABEL(bfillLongs) pushl %ebp movl %esp,%ebp pushl %edi /* put buf in %edi, nlongs in %ecx, and value in %eax */ movl ARG1(%ebp),%edi /* get buf */ movl ARG2(%ebp),%ecx /* get nlongs */ movl ARG3(%ebp),%eax /* get value */ cld rep stosl /* fill it, long by long */ popl %edi leave ret#endif /* !PORTABLE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -