mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 15:02:59 +00:00
[UCRT][ASM] Make asm code GCC compatible
This commit is contained in:
parent
4fec953e6e
commit
94eb475177
22 changed files with 698 additions and 555 deletions
|
@ -316,8 +316,10 @@ ENDM
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
/* MASM compatible ALIGN */
|
/* MASM compatible ALIGN */
|
||||||
#define ALIGN .align
|
.macro align x
|
||||||
#define align .align
|
.align x
|
||||||
|
.endm
|
||||||
|
#define ALIGN align
|
||||||
|
|
||||||
/* MASM compatible REPEAT, additional ENDR */
|
/* MASM compatible REPEAT, additional ENDR */
|
||||||
#define REPEAT .rept
|
#define REPEAT .rept
|
||||||
|
@ -352,6 +354,7 @@ ENDM
|
||||||
|
|
||||||
/* MASM needs an END tag */
|
/* MASM needs an END tag */
|
||||||
#define END
|
#define END
|
||||||
|
#define end
|
||||||
|
|
||||||
.macro .MODEL model
|
.macro .MODEL model
|
||||||
.endm
|
.endm
|
||||||
|
@ -359,6 +362,7 @@ ENDM
|
||||||
.macro .code
|
.macro .code
|
||||||
.text
|
.text
|
||||||
.endm
|
.endm
|
||||||
|
#define CODESEG .code
|
||||||
|
|
||||||
.macro .const
|
.macro .const
|
||||||
.section .rdata
|
.section .rdata
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#include <ksamd64.inc>
|
||||||
|
.code64
|
||||||
|
#if 0
|
||||||
title strcat - concatenate (append) one string to another
|
title strcat - concatenate (append) one string to another
|
||||||
;***
|
;***
|
||||||
;strcat.asm - contains strcat() and strcpy() routines
|
;strcat.asm - contains strcat() and strcpy() routines
|
||||||
|
@ -73,11 +77,12 @@ include ksamd64.inc
|
||||||
;
|
;
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
public ___entry_from_strcat_in_strcpy
|
public ___entry_from_strcat_in_strcpy
|
||||||
LEAF_ENTRY_ARG2 strcat, _TEXT, dst:ptr byte, src:ptr byte
|
LEAF_ENTRY_ARG2 strcat, _TEXT, dst_ptr_byte, src_ptr_byte
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
mov r11, rcx
|
mov r11, rcx
|
||||||
test cl, 7
|
test cl, 7
|
||||||
|
@ -94,12 +99,12 @@ strcat_copy_head_loop_begin:
|
||||||
strcat_loop_begin:
|
strcat_loop_begin:
|
||||||
mov rax, [rcx]
|
mov rax, [rcx]
|
||||||
mov r10, rax
|
mov r10, rax
|
||||||
mov r9, 7efefefefefefeffh
|
mov r9, HEX(7efefefefefefeff)
|
||||||
add r9, r10
|
add r9, r10
|
||||||
xor r10, -1
|
xor r10, -1
|
||||||
xor r10, r9
|
xor r10, r9
|
||||||
add rcx, 8
|
add rcx, 8
|
||||||
mov r9, 8101010101010100h
|
mov r9, HEX(8101010101010100)
|
||||||
test r10, r9
|
test r10, r9
|
||||||
je strcat_loop_begin
|
je strcat_loop_begin
|
||||||
sub rcx, 8
|
sub rcx, 8
|
||||||
|
@ -136,16 +141,16 @@ strcat_loop_end:
|
||||||
|
|
||||||
LEAF_END strcat, _TEXT
|
LEAF_END strcat, _TEXT
|
||||||
|
|
||||||
LEAF_ENTRY_ARG2 strcpy, _TEXT, dst:ptr byte, src:ptr byte
|
LEAF_ENTRY_ARG2 strcpy, _TEXT, dst_ptr_byte, src_ptr byte
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
mov r11, rcx
|
mov r11, rcx
|
||||||
strcat_copy:
|
strcat_copy:
|
||||||
___entry_from_strcat_in_strcpy=strcat_copy
|
___entry_from_strcat_in_strcpy=strcat_copy
|
||||||
; align the SOURCE so we never page fault
|
// align the SOURCE so we never page fault
|
||||||
; dest pointer alignment not important
|
// dest pointer alignment not important
|
||||||
sub rcx, rdx ; combine pointers
|
sub rcx, rdx // combine pointers
|
||||||
test dl, 7
|
test dl, 7
|
||||||
jz qword_loop_entrance
|
jz qword_loop_entrance
|
||||||
|
|
||||||
|
@ -168,12 +173,12 @@ qword_loop_begin:
|
||||||
add rdx, 8
|
add rdx, 8
|
||||||
qword_loop_entrance:
|
qword_loop_entrance:
|
||||||
mov rax, [rdx]
|
mov rax, [rdx]
|
||||||
mov r9, 7efefefefefefeffh
|
mov r9, HEX(7efefefefefefeff)
|
||||||
add r9, rax
|
add r9, rax
|
||||||
mov r10, rax
|
mov r10, rax
|
||||||
xor r10, -1
|
xor r10, -1
|
||||||
xor r10, r9
|
xor r10, r9
|
||||||
mov r9, 8101010101010100h
|
mov r9, HEX(8101010101010100)
|
||||||
test r10, r9
|
test r10, r9
|
||||||
jz qword_loop_begin
|
jz qword_loop_begin
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#include <ksamd64.inc>
|
||||||
|
.code64
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strcmp.asm - compare two strings
|
title strcmp.asm - compare two strings
|
||||||
;***
|
;***
|
||||||
|
@ -54,25 +58,26 @@ include ksamd64.inc
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CHAR_TYPE EQU BYTE
|
#define CHAR_TYPE BYTE
|
||||||
CHAR_PTR EQU BYTE PTR
|
#define CHAR_PTR BYTE PTR
|
||||||
CHAR_SIZE = sizeof CHAR_TYPE
|
#define CHAR_SIZE 1 /* = sizeof CHAR_TYPE */
|
||||||
|
|
||||||
BLK_TYPE EQU QWORD
|
#define BLK_TYPE QWORD
|
||||||
BLK_PTR EQU QWORD PTR
|
#define BLK_PTR QWORD PTR
|
||||||
BLK_SIZE = sizeof BLK_TYPE
|
#define BLK_SIZE 8 /* = sizeof BLK_TYPE */
|
||||||
|
|
||||||
;PAGE_SIZE = 1000h
|
//PAGE_SIZE = 1000h
|
||||||
PAGE_MASK = PAGE_SIZE - 1 ; mask for offset in MM page
|
PAGE_MASK = PAGE_SIZE - 1 // mask for offset in MM page
|
||||||
PAGE_SAFE_BLK = PAGE_SIZE - BLK_SIZE ; maximum offset for safe block compare
|
PAGE_SAFE_BLK = PAGE_SIZE - BLK_SIZE // maximum offset for safe block compare
|
||||||
|
|
||||||
LEAF_ENTRY_ARG2 strcmp, _TEXT, str1:ptr byte, str2:ptr byte
|
LEAF_ENTRY_ARG2 strcmp, _TEXT, str1_ptr_byte, str2_ptr_byte
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
; rcx = src
|
// rcx = src
|
||||||
; rdx = dst
|
// rdx = dst
|
||||||
|
|
||||||
sub rdx, rcx
|
sub rdx, rcx
|
||||||
test cl, (BLK_SIZE - 1)
|
test cl, (BLK_SIZE - 1)
|
||||||
|
@ -93,8 +98,8 @@ comp_head_loop_begin:
|
||||||
|
|
||||||
qword_loop_enter:
|
qword_loop_enter:
|
||||||
|
|
||||||
mov r11, 8080808080808080h
|
mov r11, HEX(8080808080808080)
|
||||||
mov r10, 0fefefefefefefeffh
|
mov r10, HEX(0fefefefefefefeff)
|
||||||
|
|
||||||
qword_loop_begin:
|
qword_loop_begin:
|
||||||
lea eax, [edx+ecx]
|
lea eax, [edx+ecx]
|
||||||
|
@ -105,24 +110,24 @@ qword_loop_begin:
|
||||||
mov rax, BLK_PTR[rcx]
|
mov rax, BLK_PTR[rcx]
|
||||||
cmp rax, BLK_PTR[rdx+rcx]
|
cmp rax, BLK_PTR[rdx+rcx]
|
||||||
|
|
||||||
; mismatched string (or maybe null + garbage after)
|
// mismatched string (or maybe null + garbage after)
|
||||||
jne comp_head_loop_begin
|
jne comp_head_loop_begin
|
||||||
|
|
||||||
; look for null terminator
|
// look for null terminator
|
||||||
lea r9, [rax + r10]
|
lea r9, [rax + r10]
|
||||||
not rax
|
not rax
|
||||||
add rcx, BLK_SIZE
|
add rcx, BLK_SIZE
|
||||||
and rax, r9
|
and rax, r9
|
||||||
|
|
||||||
test rax, r11 ; r11=8080808080808080h
|
test rax, r11 // r11=8080808080808080h
|
||||||
jz qword_loop_begin
|
jz qword_loop_begin
|
||||||
|
|
||||||
return_equal:
|
return_equal:
|
||||||
xor eax, eax ; gets all 64 bits
|
xor eax, eax // gets all 64 bits
|
||||||
ret
|
ret
|
||||||
|
|
||||||
return_not_equal:
|
return_not_equal:
|
||||||
sbb rax, rax ; AX=-1, CY=1 AX=0, CY=0
|
sbb rax, rax // AX=-1, CY=1 AX=0, CY=0
|
||||||
or rax, 1
|
or rax, 1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#include <ksamd64.inc>
|
||||||
|
.code64
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strlen - return the length of a null-terminated string
|
title strlen - return the length of a null-terminated string
|
||||||
;***
|
;***
|
||||||
|
@ -42,17 +46,18 @@ include ksamd64.inc
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
LEAF_ENTRY_ARG1 strlen, _TEXT, buf:ptr byte
|
LEAF_ENTRY_ARG1 strlen, _TEXT, buf:ptr byte
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
mov rax, rcx
|
mov rax, rcx
|
||||||
neg rcx ; for later
|
neg rcx // for later
|
||||||
test rax, 7
|
test rax, 7
|
||||||
jz main_loop_entry
|
jz main_loop_entry
|
||||||
|
|
||||||
byte 066h, 090h
|
.byte HEX(66), HEX(90)
|
||||||
|
|
||||||
byte_loop_begin:
|
byte_loop_begin:
|
||||||
mov dl, [rax]
|
mov dl, [rax]
|
||||||
|
@ -63,8 +68,8 @@ byte_loop_begin:
|
||||||
jnz byte_loop_begin
|
jnz byte_loop_begin
|
||||||
|
|
||||||
main_loop_entry:
|
main_loop_entry:
|
||||||
mov r8, 7efefefefefefeffh
|
mov r8, HEX(7efefefefefefeff)
|
||||||
mov r11, 8101010101010100h
|
mov r11, HEX(8101010101010100)
|
||||||
|
|
||||||
main_loop_begin:
|
main_loop_begin:
|
||||||
mov rdx, [rax]
|
mov rdx, [rax]
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#include <ksamd64.inc>
|
||||||
|
.code64
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strncat - append n chars of string1 to string2
|
title strncat - append n chars of string1 to string2
|
||||||
;***
|
;***
|
||||||
|
@ -53,8 +57,9 @@ include ksamd64.inc
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
LEAF_ENTRY_ARG3 strncat, _TEXT, front:ptr byte, back:ptr byte, count:dword
|
#endif
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
LEAF_ENTRY_ARG3 strncat, _TEXT, front_ptr_byte, back_ptr_byte, count_dword
|
||||||
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
mov r11, rcx
|
mov r11, rcx
|
||||||
or r8, r8
|
or r8, r8
|
||||||
|
@ -75,12 +80,12 @@ strncat_copy_head_loop_begin:
|
||||||
strncat_loop_begin:
|
strncat_loop_begin:
|
||||||
mov rax, [rcx]
|
mov rax, [rcx]
|
||||||
mov r10, rax
|
mov r10, rax
|
||||||
mov r9, 7efefefefefefeffh
|
mov r9, HEX(7efefefefefefeff)
|
||||||
add r9, r10
|
add r9, r10
|
||||||
xor r10, -1
|
xor r10, -1
|
||||||
xor r10, r9
|
xor r10, r9
|
||||||
add rcx, 8
|
add rcx, 8
|
||||||
mov r9, 8101010101010100h
|
mov r9, HEX(8101010101010100)
|
||||||
test r10, r9
|
test r10, r9
|
||||||
je strncat_loop_begin
|
je strncat_loop_begin
|
||||||
sub rcx, 8
|
sub rcx, 8
|
||||||
|
@ -116,9 +121,9 @@ strncat_loop_end:
|
||||||
jmp strncat_loop_begin
|
jmp strncat_loop_begin
|
||||||
|
|
||||||
strncat_copy:
|
strncat_copy:
|
||||||
; align the SOURCE so we never page fault
|
// align the SOURCE so we never page fault
|
||||||
; dest pointer alignment not important
|
// dest pointer alignment not important
|
||||||
sub rcx, rdx ; combine pointers
|
sub rcx, rdx // combine pointers
|
||||||
test dl, 7
|
test dl, 7
|
||||||
jz qword_loop_entrance
|
jz qword_loop_entrance
|
||||||
|
|
||||||
|
@ -150,12 +155,12 @@ qword_loop_entrance:
|
||||||
mov rax, [rdx]
|
mov rax, [rdx]
|
||||||
sub r8, 8
|
sub r8, 8
|
||||||
jbe qword_loop_end
|
jbe qword_loop_end
|
||||||
mov r9, 7efefefefefefeffh
|
mov r9, HEX(7efefefefefefeff)
|
||||||
add r9, rax
|
add r9, rax
|
||||||
mov r10, rax
|
mov r10, rax
|
||||||
xor r10, -1
|
xor r10, -1
|
||||||
xor r10, r9
|
xor r10, r9
|
||||||
mov r9, 8101010101010100h
|
mov r9, HEX(8101010101010100)
|
||||||
test r10, r9
|
test r10, r9
|
||||||
jz qword_loop_begin
|
jz qword_loop_begin
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#include <ksamd64.inc>
|
||||||
|
.code64
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strncmp - compare first n chars of two strings
|
title strncmp - compare first n chars of two strings
|
||||||
;***
|
;***
|
||||||
|
@ -51,14 +55,15 @@ include ksamd64.inc
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
LEAF_ENTRY_ARG3 strncmp, _TEXT, str1:ptr byte, str2:ptr byte, count:dword
|
LEAF_ENTRY_ARG3 strncmp, _TEXT, str1_ptr_byte, str2_ptr_byte, count_dword
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
; rcx = first
|
// rcx = first
|
||||||
; rdx = last
|
// rdx = last
|
||||||
; r8 = count
|
// r8 = count
|
||||||
|
|
||||||
sub rdx, rcx
|
sub rdx, rcx
|
||||||
|
|
||||||
|
@ -85,13 +90,13 @@ comp_head_loop_begin:
|
||||||
jnz comp_head_loop_begin
|
jnz comp_head_loop_begin
|
||||||
|
|
||||||
qword_loop_enter:
|
qword_loop_enter:
|
||||||
mov r11, 08080808080808080h
|
mov r11, HEX(08080808080808080)
|
||||||
mov r10, 0fefefefefefefeffh
|
mov r10, HEX(0fefefefefefefeff)
|
||||||
|
|
||||||
qword_loop_begin:
|
qword_loop_begin:
|
||||||
lea eax, [rdx+rcx]
|
lea eax, [rdx+rcx]
|
||||||
and eax, 0fffh
|
and eax, HEX(0fff)
|
||||||
cmp eax, 0ff8h
|
cmp eax, HEX(0ff8)
|
||||||
ja comp_head_loop_begin
|
ja comp_head_loop_begin
|
||||||
|
|
||||||
mov rax, qword ptr[rcx]
|
mov rax, qword ptr[rcx]
|
||||||
|
@ -106,7 +111,7 @@ qword_loop_begin:
|
||||||
lea r9, [r10+rax]
|
lea r9, [r10+rax]
|
||||||
not rax
|
not rax
|
||||||
and rax, r9
|
and rax, r9
|
||||||
test rax, r11 ; 8080808080808080h
|
test rax, r11 // 8080808080808080h
|
||||||
|
|
||||||
jz qword_loop_begin
|
jz qword_loop_begin
|
||||||
|
|
||||||
|
@ -114,10 +119,10 @@ return_equal:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; align 16
|
// align 16
|
||||||
|
|
||||||
return_not_equal:
|
return_not_equal:
|
||||||
sbb rax, rax ; AX=-1, CY=1 AX=0, CY=0
|
sbb rax, rax // AX=-1, CY=1 AX=0, CY=0
|
||||||
or rax, 1
|
or rax, 1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#include <ksamd64.inc>
|
||||||
|
.code64
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strncpy - copy at most n characters of string
|
title strncpy - copy at most n characters of string
|
||||||
;***
|
;***
|
||||||
|
@ -12,17 +16,18 @@
|
||||||
; Look at strncat.asm for this file
|
; Look at strncat.asm for this file
|
||||||
include ksamd64.inc
|
include ksamd64.inc
|
||||||
subttl "strncpy"
|
subttl "strncpy"
|
||||||
|
#endif
|
||||||
|
|
||||||
LEAF_ENTRY_ARG3 strncpy, _TEXT, dst:ptr byte, src:ptr byte, count:dword
|
LEAF_ENTRY_ARG3 strncpy, _TEXT, dst_ptr_byte, src_ptr_byte, count_dword
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
; align the SOURCE so we never page fault
|
// align the SOURCE so we never page fault
|
||||||
; dest pointer alignment not important
|
// dest pointer alignment not important
|
||||||
|
|
||||||
mov r11, rcx
|
mov r11, rcx
|
||||||
or r8, r8
|
or r8, r8
|
||||||
jz strncpy_exit
|
jz strncpy_exit
|
||||||
sub rcx, rdx ; combine pointers
|
sub rcx, rdx // combine pointers
|
||||||
test dl, 7
|
test dl, 7
|
||||||
jz qword_loop_entrance
|
jz qword_loop_entrance
|
||||||
|
|
||||||
|
@ -49,12 +54,12 @@ qword_loop_entrance:
|
||||||
mov rax, [rdx]
|
mov rax, [rdx]
|
||||||
sub r8, 8
|
sub r8, 8
|
||||||
jbe qword_loop_end
|
jbe qword_loop_end
|
||||||
mov r9, 7efefefefefefeffh
|
mov r9, HEX(7efefefefefefeff)
|
||||||
add r9, rax
|
add r9, rax
|
||||||
mov r10, rax
|
mov r10, rax
|
||||||
xor r10, -1
|
xor r10, -1
|
||||||
xor r10, r9
|
xor r10, r9
|
||||||
mov r9, 8101010101010100h
|
mov r9, HEX(8101010101010100)
|
||||||
test r10, r9
|
test r10, r9
|
||||||
jz qword_loop_begin
|
jz qword_loop_begin
|
||||||
|
|
||||||
|
@ -118,12 +123,12 @@ strncpy_exit_2:
|
||||||
mov rax, r11
|
mov rax, r11
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;this is really just memset
|
//this is really just memset
|
||||||
filler:
|
filler:
|
||||||
add rcx, rdx
|
add rcx, rdx
|
||||||
xor rdx, rdx
|
xor rdx, rdx
|
||||||
cmp r8, 16
|
cmp r8, 16
|
||||||
jb tail ; a quickie
|
jb tail // a quickie
|
||||||
aligner1:
|
aligner1:
|
||||||
test cl, 7
|
test cl, 7
|
||||||
jz aligned
|
jz aligned
|
||||||
|
@ -144,7 +149,7 @@ loop32:
|
||||||
jae loop32
|
jae loop32
|
||||||
|
|
||||||
tail_8_enter:
|
tail_8_enter:
|
||||||
add r8, 32 ; get back the value
|
add r8, 32 // get back the value
|
||||||
tail_8_begin:
|
tail_8_begin:
|
||||||
sub r8, 8
|
sub r8, 8
|
||||||
jb tail_enter
|
jb tail_enter
|
||||||
|
@ -153,7 +158,7 @@ tail_8_begin:
|
||||||
jmp tail_8_begin
|
jmp tail_8_begin
|
||||||
|
|
||||||
tail_enter:
|
tail_enter:
|
||||||
add r8, 8 ; get back the value
|
add r8, 8 // get back the value
|
||||||
tail:
|
tail:
|
||||||
sub r8, 1
|
sub r8, 1
|
||||||
jb tail_finish
|
jb tail_finish
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title memicmp - compare blocks of memory, ignore case
|
title memicmp - compare blocks of memory, ignore case
|
||||||
;***
|
;***
|
||||||
|
@ -54,77 +56,90 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
public __ascii_memicmp
|
public ___ascii_memicmp
|
||||||
__ascii_memicmp proc \
|
.PROC ___ascii_memicmp
|
||||||
uses edi esi ebx, \
|
|
||||||
first:ptr byte, \
|
|
||||||
last:ptr byte, \
|
|
||||||
count:IWORD
|
|
||||||
|
|
||||||
mov ecx,[count] ; cx = count
|
// Prolog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
|
push ebp
|
||||||
|
mov ebp, esp
|
||||||
|
push edi
|
||||||
|
push esi
|
||||||
|
push ebx
|
||||||
|
#define first ebp + 8
|
||||||
|
#define last ebp + 12
|
||||||
|
#define count ebp + 16
|
||||||
|
|
||||||
|
mov ecx,[count] // cx = count
|
||||||
or ecx,ecx
|
or ecx,ecx
|
||||||
jz short toend ; if count=0, nothing to do
|
jz short toend // if count=0, nothing to do
|
||||||
|
|
||||||
mov esi,[first] ; si = first
|
mov esi,[first] // si = first
|
||||||
mov edi,[last] ; di = last
|
mov edi,[last] // di = last
|
||||||
|
|
||||||
; C locale
|
// C locale
|
||||||
|
|
||||||
mov bh,'A'
|
mov bh,'A'
|
||||||
mov bl,'Z'
|
mov bl,'Z'
|
||||||
mov dh,'a'-'A' ; add to cap to make lower
|
mov dh,'a'-'A' // add to cap to make lower
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
|
|
||||||
lupe:
|
lupe:
|
||||||
mov ah,[esi] ; ah = *first
|
mov ah,[esi] // ah = *first
|
||||||
add esi,1 ; first++
|
add esi,1 // first++
|
||||||
mov al,[edi] ; al = *last
|
mov al,[edi] // al = *last
|
||||||
add edi,1 ; last++
|
add edi,1 // last++
|
||||||
|
|
||||||
cmp ah,al ; test for equality BEFORE converting case
|
cmp ah,al // test for equality BEFORE converting case
|
||||||
je short dolupe
|
je short dolupe
|
||||||
|
|
||||||
cmp ah,bh ; ah < 'A' ??
|
cmp ah,bh // ah < 'A' ??
|
||||||
jb short skip1
|
jb short skip1
|
||||||
|
|
||||||
cmp ah,bl ; ah > 'Z' ??
|
cmp ah,bl // ah > 'Z' ??
|
||||||
ja short skip1
|
ja short skip1
|
||||||
|
|
||||||
add ah,dh ; make lower case
|
add ah,dh // make lower case
|
||||||
|
|
||||||
skip1:
|
skip1:
|
||||||
cmp al,bh ; al < 'A' ??
|
cmp al,bh // al < 'A' ??
|
||||||
jb short skip2
|
jb short skip2
|
||||||
|
|
||||||
cmp al,bl ; al > 'Z' ??
|
cmp al,bl // al > 'Z' ??
|
||||||
ja short skip2
|
ja short skip2
|
||||||
|
|
||||||
add al,dh ; make lower case
|
add al,dh // make lower case
|
||||||
|
|
||||||
skip2:
|
skip2:
|
||||||
cmp ah,al ; *first == *last ??
|
cmp ah,al // *first == *last ??
|
||||||
jne short differ ; nope, found mismatched chars
|
jne short differ // nope, found mismatched chars
|
||||||
|
|
||||||
dolupe:
|
dolupe:
|
||||||
sub ecx,1
|
sub ecx,1
|
||||||
jnz short lupe
|
jnz short lupe
|
||||||
|
|
||||||
jmp short toend ; cx = 0, return 0
|
jmp short toend // cx = 0, return 0
|
||||||
|
|
||||||
differ:
|
differ:
|
||||||
mov ecx,-1 ; assume last is bigger
|
mov ecx,-1 // assume last is bigger
|
||||||
; *** can't use "or ecx,-1" due to flags ***
|
// *** can't use "or ecx,-1" due to flags ***
|
||||||
jb short toend ; last is, in fact, bigger (return -1)
|
jb short toend // last is, in fact, bigger (return -1)
|
||||||
neg ecx ; first is bigger (return 1)
|
neg ecx // first is bigger (return 1)
|
||||||
|
|
||||||
toend:
|
toend:
|
||||||
mov eax,ecx ; move return value to ax
|
mov eax,ecx // move return value to ax
|
||||||
|
|
||||||
ret ; _cdecl return
|
// Epilog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
|
pop ebx
|
||||||
|
pop esi
|
||||||
|
pop edi
|
||||||
|
pop ebp
|
||||||
|
|
||||||
__ascii_memicmp endp
|
ret // _cdecl return
|
||||||
|
|
||||||
|
.ENDP // ___ascii_memicmp
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strnicmp - compare n chars of strings, ignore case
|
title strnicmp - compare n chars of strings, ignore case
|
||||||
;***
|
;***
|
||||||
|
@ -62,63 +64,69 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
public __ascii_strnicmp
|
public ___ascii_strnicmp
|
||||||
__ascii_strnicmp proc \
|
.PROC ___ascii_strnicmp
|
||||||
uses edi esi ebx, \
|
// Prolog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
first:ptr byte, \
|
push ebp
|
||||||
last:ptr byte, \
|
mov ebp, esp
|
||||||
count:IWORD
|
push edi // uses edi esi ebx
|
||||||
|
push esi
|
||||||
|
push ebx
|
||||||
|
#define first ebp + 8 // first:ptr byte
|
||||||
|
#define last ebp + 12 // last:ptr byte
|
||||||
|
#define count ebp + 16 // count:IWORD
|
||||||
|
|
||||||
mov ecx,[count] ; cx = byte count
|
mov ecx,[count] // cx = byte count
|
||||||
or ecx,ecx
|
or ecx,ecx
|
||||||
jz toend ; if count = 0, we are done
|
jz toend // if count = 0, we are done
|
||||||
|
|
||||||
mov esi,[first] ; si = first string
|
mov esi,[first] // si = first string
|
||||||
mov edi,[last] ; di = last string
|
mov edi,[last] // di = last string
|
||||||
|
|
||||||
mov bh,'A'
|
mov bh,'A'
|
||||||
mov bl,'Z'
|
mov bl,'Z'
|
||||||
mov dh,'a'-'A' ; add to cap to make lower
|
mov dh,'a'-'A' // add to cap to make lower
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
|
|
||||||
lupe:
|
lupe:
|
||||||
mov ah,[esi] ; *first
|
mov ah,[esi] // *first
|
||||||
|
|
||||||
or ah,ah ; see if *first is null
|
or ah,ah // see if *first is null
|
||||||
|
|
||||||
mov al,[edi] ; *last
|
mov al,[edi] // *last
|
||||||
|
|
||||||
jz short eject ; jump if *first is null
|
jz short eject // jump if *first is null
|
||||||
|
|
||||||
or al,al ; see if *last is null
|
or al,al // see if *last is null
|
||||||
jz short eject ; jump if so
|
jz short eject // jump if so
|
||||||
|
|
||||||
add esi,1 ; first++
|
add esi,1 // first++
|
||||||
add edi,1 ; last++
|
add edi,1 // last++
|
||||||
|
|
||||||
cmp ah,bh ; 'A'
|
cmp ah,bh // 'A'
|
||||||
jb short skip1
|
jb short skip1
|
||||||
|
|
||||||
cmp ah,bl ; 'Z'
|
cmp ah,bl // 'Z'
|
||||||
ja short skip1
|
ja short skip1
|
||||||
|
|
||||||
add ah,dh ; make lower case
|
add ah,dh // make lower case
|
||||||
|
|
||||||
skip1:
|
skip1:
|
||||||
cmp al,bh ; 'A'
|
cmp al,bh // 'A'
|
||||||
jb short skip2
|
jb short skip2
|
||||||
|
|
||||||
cmp al,bl ; 'Z'
|
cmp al,bl // 'Z'
|
||||||
ja short skip2
|
ja short skip2
|
||||||
|
|
||||||
add al,dh ; make lower case
|
add al,dh // make lower case
|
||||||
|
|
||||||
skip2:
|
skip2:
|
||||||
cmp ah,al ; *first == *last ??
|
cmp ah,al // *first == *last ??
|
||||||
jne short differ
|
jne short differ
|
||||||
|
|
||||||
sub ecx,1
|
sub ecx,1
|
||||||
|
@ -126,18 +134,24 @@ skip2:
|
||||||
|
|
||||||
eject:
|
eject:
|
||||||
xor ecx,ecx
|
xor ecx,ecx
|
||||||
cmp ah,al ; compare the (possibly) differing bytes
|
cmp ah,al // compare the (possibly) differing bytes
|
||||||
je short toend ; both zero; return 0
|
je short toend // both zero; return 0
|
||||||
|
|
||||||
differ:
|
differ:
|
||||||
mov ecx,-1 ; assume last is bigger (* can't use 'or' *)
|
mov ecx,-1 // assume last is bigger (* can't use 'or' *)
|
||||||
jb short toend ; last is, in fact, bigger (return -1)
|
jb short toend // last is, in fact, bigger (return -1)
|
||||||
neg ecx ; first is bigger (return 1)
|
neg ecx // first is bigger (return 1)
|
||||||
|
|
||||||
toend:
|
toend:
|
||||||
mov eax,ecx
|
mov eax,ecx
|
||||||
|
|
||||||
ret ; _cdecl return
|
// Epilog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
|
pop ebx
|
||||||
|
pop esi
|
||||||
|
pop edi
|
||||||
|
pop ebp
|
||||||
|
|
||||||
__ascii_strnicmp endp
|
ret // _cdecl return
|
||||||
|
|
||||||
|
.ENDP // ___ascii_strnicmp
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title memccpy - copy bytes until character found
|
title memccpy - copy bytes until character found
|
||||||
;***
|
;***
|
||||||
|
@ -51,85 +53,86 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
public _memccpy
|
public __memccpy
|
||||||
_memccpy proc \
|
.PROC __memccpy
|
||||||
dest:ptr byte, \
|
// dest:ptr byte, \
|
||||||
src:ptr byte, \
|
// src:ptr byte, \
|
||||||
_c:byte, \
|
// _c:byte, \
|
||||||
count:DWORD
|
// count:DWORD
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
.FPO ( 0, 4, 0, 0, 0, 0 )
|
FPO 0, 4, 0, 0, 0, 0
|
||||||
|
|
||||||
mov ecx,[esp + 10h] ; ecx = max byte count
|
mov ecx,[esp + HEX(10)] // ecx = max byte count
|
||||||
push ebx ; save ebx
|
push ebx // save ebx
|
||||||
|
|
||||||
test ecx,ecx ; if it's nothing to move
|
test ecx,ecx // if it's nothing to move
|
||||||
jz ret_zero_len ; restore ebx, and return NULL
|
jz ret_zero_len // restore ebx, and return NULL
|
||||||
|
|
||||||
mov bh,[esp + 10h] ; bh = byte to look for
|
mov bh,[esp + HEX(10)] // bh = byte to look for
|
||||||
push esi ; save esi
|
push esi // save esi
|
||||||
|
|
||||||
test ecx,1 ; test if counter is odd or even
|
test ecx,1 // test if counter is odd or even
|
||||||
|
|
||||||
mov eax,[esp + 0ch] ; eax = dest , don't affect flags
|
mov eax,[esp + HEX(0c)] // eax = dest , don't affect flags
|
||||||
mov esi,[esp + 10h] ; esi = source , don't affect flags
|
mov esi,[esp + HEX(10)] // esi = source , don't affect flags
|
||||||
|
|
||||||
; nop
|
// nop
|
||||||
jz lupe2 ; if counter is even, do double loop
|
jz lupe2 // if counter is even, do double loop
|
||||||
; else do one iteration, and drop into double loop
|
// else do one iteration, and drop into double loop
|
||||||
mov bl,[esi] ; get first byte into bl
|
mov bl,[esi] // get first byte into bl
|
||||||
add esi,1 ; kick src (esi points to src)
|
add esi,1 // kick src (esi points to src)
|
||||||
|
|
||||||
mov [eax],bl ; store it in dest
|
mov [eax],bl // store it in dest
|
||||||
add eax,1 ; kick dest
|
add eax,1 // kick dest
|
||||||
|
|
||||||
cmp bl,bh ; see if we just moved the byte
|
cmp bl,bh // see if we just moved the byte
|
||||||
je short toend
|
je short toend
|
||||||
|
|
||||||
sub ecx,1 ; decrement counter
|
sub ecx,1 // decrement counter
|
||||||
jz retnull ; drop into double loop if nonzero
|
jz retnull // drop into double loop if nonzero
|
||||||
|
|
||||||
lupe2:
|
lupe2:
|
||||||
mov bl,[esi] ; get first byte into bl
|
mov bl,[esi] // get first byte into bl
|
||||||
add esi,2 ; kick esi (src)
|
add esi,2 // kick esi (src)
|
||||||
|
|
||||||
cmp bl,bh ; check if we just moved the byte (from bl)
|
cmp bl,bh // check if we just moved the byte (from bl)
|
||||||
je toend_mov_inc ; store bl & exit
|
je toend_mov_inc // store bl & exit
|
||||||
|
|
||||||
mov [eax],bl ; store first byte from bl
|
mov [eax],bl // store first byte from bl
|
||||||
mov bl,[esi - 1] ; get second byte into bl
|
mov bl,[esi - 1] // get second byte into bl
|
||||||
|
|
||||||
mov [eax + 1],bl ; store second byte from bl
|
mov [eax + 1],bl // store second byte from bl
|
||||||
add eax,2 ; kick eax (dest)
|
add eax,2 // kick eax (dest)
|
||||||
|
|
||||||
cmp bl,bh ; see if we just moved the byte
|
cmp bl,bh // see if we just moved the byte
|
||||||
je short toend ; end of string
|
je short toend // end of string
|
||||||
|
|
||||||
sub ecx,2 ; modify counter, and if nonzero continue
|
sub ecx,2 // modify counter, and if nonzero continue
|
||||||
jnz lupe2 ; else drop out & return NULL
|
jnz lupe2 // else drop out & return NULL
|
||||||
|
|
||||||
retnull:
|
retnull:
|
||||||
pop esi
|
pop esi
|
||||||
ret_zero_len:
|
ret_zero_len:
|
||||||
xor eax,eax ; null pointer
|
xor eax,eax // null pointer
|
||||||
pop ebx
|
pop ebx
|
||||||
|
|
||||||
ret ; _cdecl return
|
ret // _cdecl return
|
||||||
|
|
||||||
toend_mov_inc:
|
toend_mov_inc:
|
||||||
mov [eax],bl ; store first byte from bl
|
mov [eax],bl // store first byte from bl
|
||||||
add eax,1 ; eax points right after the value
|
add eax,1 // eax points right after the value
|
||||||
|
|
||||||
toend: pop esi
|
toend: pop esi
|
||||||
pop ebx
|
pop ebx
|
||||||
|
|
||||||
ret ; _cdecl return
|
ret // _cdecl return
|
||||||
|
|
||||||
_memccpy endp
|
.ENDP // __memccpy
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strcat - concatenate (append) one string to another
|
title strcat - concatenate (append) one string to another
|
||||||
;***
|
;***
|
||||||
|
@ -80,39 +82,41 @@ page
|
||||||
;
|
;
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
% public strcat, strcpy ; make both functions available
|
public _strcat
|
||||||
strcpy proc \
|
public _strcpy // make both functions available
|
||||||
dst:ptr byte, \
|
.PROC _strcpy
|
||||||
src:ptr byte
|
// dst:ptr byte, \
|
||||||
|
// src:ptr byte
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
push edi ; preserve edi
|
push edi // preserve edi
|
||||||
mov edi,[esp+8] ; edi points to dest string
|
mov edi,[esp+8] // edi points to dest string
|
||||||
jmp short copy_start
|
jmp short copy_start
|
||||||
|
|
||||||
strcpy endp
|
.ENDP // _strcpy
|
||||||
|
|
||||||
align 16
|
align 16
|
||||||
|
|
||||||
strcat proc \
|
.PROC _strcat
|
||||||
dst:ptr byte, \
|
// dst:ptr byte, \
|
||||||
src:ptr byte
|
// src:ptr byte
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
.FPO ( 0, 2, 0, 0, 0, 0 )
|
FPO 0, 2, 0, 0, 0, 0
|
||||||
|
|
||||||
mov ecx,[esp+4] ; ecx -> dest string
|
mov ecx,[esp+4] // ecx -> dest string
|
||||||
push edi ; preserve edi
|
push edi // preserve edi
|
||||||
test ecx,3 ; test if string is aligned on 32 bits
|
test ecx,3 // test if string is aligned on 32 bits
|
||||||
je short find_end_of_dest_string_loop
|
je short find_end_of_dest_string_loop
|
||||||
|
|
||||||
dest_misaligned: ; simple byte loop until string is aligned
|
dest_misaligned: // simple byte loop until string is aligned
|
||||||
mov al,byte ptr [ecx]
|
mov al,byte ptr [ecx]
|
||||||
add ecx,1
|
add ecx,1
|
||||||
test al,al
|
test al,al
|
||||||
|
@ -123,27 +127,27 @@ dest_misaligned: ; simple byte loop until string is aligned
|
||||||
align 4
|
align 4
|
||||||
|
|
||||||
find_end_of_dest_string_loop:
|
find_end_of_dest_string_loop:
|
||||||
mov eax,dword ptr [ecx] ; read 4 bytes
|
mov eax,dword ptr [ecx] // read 4 bytes
|
||||||
mov edx,7efefeffh
|
mov edx,HEX(7efefeff)
|
||||||
add edx,eax
|
add edx,eax
|
||||||
xor eax,-1
|
xor eax,-1
|
||||||
xor eax,edx
|
xor eax,edx
|
||||||
add ecx,4
|
add ecx,4
|
||||||
test eax,81010100h
|
test eax,HEX(81010100)
|
||||||
je short find_end_of_dest_string_loop
|
je short find_end_of_dest_string_loop
|
||||||
; found zero byte in the loop
|
// found zero byte in the loop
|
||||||
mov eax,[ecx - 4]
|
mov eax,[ecx - 4]
|
||||||
test al,al ; is it byte 0
|
test al,al // is it byte 0
|
||||||
je short start_byte_0
|
je short start_byte_0
|
||||||
test ah,ah ; is it byte 1
|
test ah,ah // is it byte 1
|
||||||
je short start_byte_1
|
je short start_byte_1
|
||||||
test eax,00ff0000h ; is it byte 2
|
test eax,HEX(00ff0000) // is it byte 2
|
||||||
je short start_byte_2
|
je short start_byte_2
|
||||||
test eax,0ff000000h ; is it byte 3
|
test eax,HEX(0ff000000) // is it byte 3
|
||||||
je short start_byte_3
|
je short start_byte_3
|
||||||
jmp short find_end_of_dest_string_loop
|
jmp short find_end_of_dest_string_loop
|
||||||
; taken if bits 24-30 are clear and bit
|
// taken if bits 24-30 are clear and bit
|
||||||
; 31 is set
|
// 31 is set
|
||||||
start_byte_3:
|
start_byte_3:
|
||||||
lea edi,[ecx - 1]
|
lea edi,[ecx - 1]
|
||||||
jmp short copy_start
|
jmp short copy_start
|
||||||
|
@ -155,15 +159,15 @@ start_byte_1:
|
||||||
jmp short copy_start
|
jmp short copy_start
|
||||||
start_byte_0:
|
start_byte_0:
|
||||||
lea edi,[ecx - 4]
|
lea edi,[ecx - 4]
|
||||||
; jmp short copy_start
|
// jmp short copy_start
|
||||||
|
|
||||||
; edi points to the end of dest string.
|
// edi points to the end of dest string.
|
||||||
copy_start::
|
GLOBAL_LABEL copy_start
|
||||||
mov ecx,[esp+0ch] ; ecx -> sorc string
|
mov ecx,[esp+HEX(0c)] // ecx -> sorc string
|
||||||
test ecx,3 ; test if string is aligned on 32 bits
|
test ecx,3 // test if string is aligned on 32 bits
|
||||||
je short main_loop_entrance
|
je short main_loop_entrance
|
||||||
|
|
||||||
src_misaligned: ; simple byte loop until string is aligned
|
src_misaligned: // simple byte loop until string is aligned
|
||||||
mov dl,byte ptr [ecx]
|
mov dl,byte ptr [ecx]
|
||||||
add ecx,1
|
add ecx,1
|
||||||
test dl,dl
|
test dl,dl
|
||||||
|
@ -174,58 +178,58 @@ src_misaligned: ; simple byte loop until string is aligned
|
||||||
jne short src_misaligned
|
jne short src_misaligned
|
||||||
jmp short main_loop_entrance
|
jmp short main_loop_entrance
|
||||||
|
|
||||||
main_loop: ; edx contains first dword of sorc string
|
main_loop: // edx contains first dword of sorc string
|
||||||
mov [edi],edx ; store one more dword
|
mov [edi],edx // store one more dword
|
||||||
add edi,4 ; kick dest pointer
|
add edi,4 // kick dest pointer
|
||||||
main_loop_entrance:
|
main_loop_entrance:
|
||||||
mov edx,7efefeffh
|
mov edx,HEX(7efefeff)
|
||||||
mov eax,dword ptr [ecx] ; read 4 bytes
|
mov eax,dword ptr [ecx] // read 4 bytes
|
||||||
|
|
||||||
add edx,eax
|
add edx,eax
|
||||||
xor eax,-1
|
xor eax,-1
|
||||||
|
|
||||||
xor eax,edx
|
xor eax,edx
|
||||||
mov edx,[ecx] ; it's in cache now
|
mov edx,[ecx] // it's in cache now
|
||||||
|
|
||||||
add ecx,4 ; kick dest pointer
|
add ecx,4 // kick dest pointer
|
||||||
test eax,81010100h
|
test eax,HEX(81010100)
|
||||||
|
|
||||||
je short main_loop
|
je short main_loop
|
||||||
; found zero byte in the loop
|
// found zero byte in the loop
|
||||||
; main_loop_end:
|
; main_loop_end:
|
||||||
test dl,dl ; is it byte 0
|
test dl,dl // is it byte 0
|
||||||
je short byte_0
|
je short byte_0
|
||||||
test dh,dh ; is it byte 1
|
test dh,dh // is it byte 1
|
||||||
je short byte_1
|
je short byte_1
|
||||||
test edx,00ff0000h ; is it byte 2
|
test edx,HEX(00ff0000) // is it byte 2
|
||||||
je short byte_2
|
je short byte_2
|
||||||
test edx,0ff000000h ; is it byte 3
|
test edx,HEX(0ff000000) // is it byte 3
|
||||||
je short byte_3
|
je short byte_3
|
||||||
jmp short main_loop ; taken if bits 24-30 are clear and bit
|
jmp short main_loop // taken if bits 24-30 are clear and bit
|
||||||
; 31 is set
|
// 31 is set
|
||||||
byte_3:
|
byte_3:
|
||||||
mov [edi],edx
|
mov [edi],edx
|
||||||
mov eax,[esp+8] ; return in eax pointer to dest string
|
mov eax,[esp+8] // return in eax pointer to dest string
|
||||||
pop edi
|
pop edi
|
||||||
ret
|
ret
|
||||||
byte_2:
|
byte_2:
|
||||||
mov [edi],dx
|
mov [edi],dx
|
||||||
mov eax,[esp+8] ; return in eax pointer to dest string
|
mov eax,[esp+8] // return in eax pointer to dest string
|
||||||
mov byte ptr [edi+2],0
|
mov byte ptr [edi+2],0
|
||||||
pop edi
|
pop edi
|
||||||
ret
|
ret
|
||||||
byte_1:
|
byte_1:
|
||||||
mov [edi],dx
|
mov [edi],dx
|
||||||
mov eax,[esp+8] ; return in eax pointer to dest string
|
mov eax,[esp+8] // return in eax pointer to dest string
|
||||||
pop edi
|
pop edi
|
||||||
ret
|
ret
|
||||||
byte_0:
|
byte_0:
|
||||||
mov [edi],dl
|
mov [edi],dl
|
||||||
mov eax,[esp+8] ; return in eax pointer to dest string
|
mov eax,[esp+8] // return in eax pointer to dest string
|
||||||
pop edi
|
pop edi
|
||||||
ret
|
ret
|
||||||
|
|
||||||
strcat endp
|
.ENDP // _strcat
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strcmp.asm - compare two strings
|
title strcmp.asm - compare two strings
|
||||||
;***
|
;***
|
||||||
|
@ -58,21 +60,22 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
public strcmp
|
public _strcmp
|
||||||
strcmp proc \
|
.PROC _strcmp
|
||||||
str1:ptr byte, \
|
// str1:ptr byte, \
|
||||||
str2:ptr byte
|
// str2:ptr byte
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
; .FPO (cdwLocals, cdwParams, cbProlog, cbRegs, fUseBP, cbFrame)
|
// .FPO (cdwLocals, cdwParams, cbProlog, cbRegs, fUseBP, cbFrame)
|
||||||
.FPO ( 0, 2, 0, 0, 0, 0 )
|
FPO 0, 2, 0, 0, 0, 0
|
||||||
|
|
||||||
mov edx,[esp + 4] ; edx = src
|
mov edx,[esp + 4] // edx = src
|
||||||
mov ecx,[esp + 8] ; ecx = dst
|
mov ecx,[esp + 8] // ecx = dst
|
||||||
|
|
||||||
test edx,3
|
test edx,3
|
||||||
jnz short dopartial
|
jnz short dopartial
|
||||||
|
@ -110,8 +113,8 @@ doneeq:
|
||||||
|
|
||||||
align 8
|
align 8
|
||||||
donene:
|
donene:
|
||||||
; The instructions below should place -1 in eax if src < dst,
|
// The instructions below should place -1 in eax if src < dst,
|
||||||
; and 1 in eax if src > dst.
|
// and 1 in eax if src > dst.
|
||||||
|
|
||||||
sbb eax,eax
|
sbb eax,eax
|
||||||
or eax,1
|
or eax,1
|
||||||
|
@ -149,6 +152,6 @@ doword:
|
||||||
add ecx,2
|
add ecx,2
|
||||||
jmp short dodwords
|
jmp short dodwords
|
||||||
|
|
||||||
strcmp endp
|
.ENDP // _strcmp
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#if 0
|
||||||
;***
|
;***
|
||||||
;strcspn.asm -
|
;strcspn.asm -
|
||||||
;
|
;
|
||||||
|
@ -14,3 +15,7 @@
|
||||||
|
|
||||||
SSTRCSPN EQU 1
|
SSTRCSPN EQU 1
|
||||||
INCLUDE STRSPN.ASM
|
INCLUDE STRSPN.ASM
|
||||||
|
#else
|
||||||
|
#define SSTRCSPN 1
|
||||||
|
#include "strspn.s"
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strlen - return the length of a null-terminated string
|
title strlen - return the length of a null-terminated string
|
||||||
;***
|
;***
|
||||||
|
@ -46,26 +48,27 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
public strlen
|
public _strlen
|
||||||
|
|
||||||
strlen proc \
|
.PROC _strlen
|
||||||
buf:ptr byte
|
// buf:ptr byte
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
.FPO ( 0, 1, 0, 0, 0, 0 )
|
FPO 0, 1, 0, 0, 0, 0
|
||||||
|
|
||||||
string equ [esp + 4]
|
#define string [esp + 4]
|
||||||
|
|
||||||
mov ecx,string ; ecx -> string
|
mov ecx,string // ecx -> string
|
||||||
test ecx,3 ; test if string is aligned on 32 bits
|
test ecx,3 // test if string is aligned on 32 bits
|
||||||
je short main_loop
|
je short main_loop
|
||||||
|
|
||||||
str_misaligned:
|
str_misaligned:
|
||||||
; simple byte loop until string is aligned
|
// simple byte loop until string is aligned
|
||||||
mov al,byte ptr [ecx]
|
mov al,byte ptr [ecx]
|
||||||
add ecx,1
|
add ecx,1
|
||||||
test al,al
|
test al,al
|
||||||
|
@ -73,31 +76,31 @@ str_misaligned:
|
||||||
test ecx,3
|
test ecx,3
|
||||||
jne short str_misaligned
|
jne short str_misaligned
|
||||||
|
|
||||||
add eax,dword ptr 0 ; 5 byte nop to align label below
|
add eax,dword ptr 0 // 5 byte nop to align label below
|
||||||
|
|
||||||
align 16 ; should be redundant
|
align 16 // should be redundant
|
||||||
|
|
||||||
main_loop:
|
main_loop:
|
||||||
mov eax,dword ptr [ecx] ; read 4 bytes
|
mov eax,dword ptr [ecx] // read 4 bytes
|
||||||
mov edx,7efefeffh
|
mov edx,HEX(7efefeff)
|
||||||
add edx,eax
|
add edx,eax
|
||||||
xor eax,-1
|
xor eax,-1
|
||||||
xor eax,edx
|
xor eax,edx
|
||||||
add ecx,4
|
add ecx,4
|
||||||
test eax,81010100h
|
test eax,HEX(81010100)
|
||||||
je short main_loop
|
je short main_loop
|
||||||
; found zero byte in the loop
|
// found zero byte in the loop
|
||||||
mov eax,[ecx - 4]
|
mov eax,[ecx - 4]
|
||||||
test al,al ; is it byte 0
|
test al,al // is it byte 0
|
||||||
je short byte_0
|
je short byte_0
|
||||||
test ah,ah ; is it byte 1
|
test ah,ah // is it byte 1
|
||||||
je short byte_1
|
je short byte_1
|
||||||
test eax,00ff0000h ; is it byte 2
|
test eax,HEX(00ff0000) // is it byte 2
|
||||||
je short byte_2
|
je short byte_2
|
||||||
test eax,0ff000000h ; is it byte 3
|
test eax,HEX(0ff000000) // is it byte 3
|
||||||
je short byte_3
|
je short byte_3
|
||||||
jmp short main_loop ; taken if bits 24-30 are clear and bit
|
jmp short main_loop // taken if bits 24-30 are clear and bit
|
||||||
; 31 is set
|
// 31 is set
|
||||||
|
|
||||||
byte_3:
|
byte_3:
|
||||||
lea eax,[ecx - 1]
|
lea eax,[ecx - 1]
|
||||||
|
@ -120,6 +123,6 @@ byte_0:
|
||||||
sub eax,ecx
|
sub eax,ecx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
strlen endp
|
.ENDP // _strlen
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strncat - append n chars of string1 to string2
|
title strncat - append n chars of string1 to string2
|
||||||
;***
|
;***
|
||||||
|
@ -57,29 +59,30 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
public strncat
|
public _strncat
|
||||||
strncat proc
|
.PROC _strncat
|
||||||
; front:ptr byte,
|
// front:ptr byte,
|
||||||
; back:ptr byte,
|
// back:ptr byte,
|
||||||
; count:IWORD
|
// count:IWORD
|
||||||
|
|
||||||
.FPO ( 0, 3, 0, 0, 0, 0 )
|
FPO 0, 3, 0, 0, 0, 0
|
||||||
|
|
||||||
mov ecx,[esp + 0ch] ; ecx = count
|
mov ecx,[esp + HEX(0c)] // ecx = count
|
||||||
push edi ; preserve edi
|
push edi // preserve edi
|
||||||
test ecx,ecx
|
test ecx,ecx
|
||||||
jz finish ; leave if count is zero
|
jz finish // leave if count is zero
|
||||||
|
|
||||||
mov edi,[esp + 8] ; edi -> front string
|
mov edi,[esp + 8] // edi -> front string
|
||||||
push esi ; preserve esi
|
push esi // preserve esi
|
||||||
test edi,3 ; is string aligned on dword (4 bytes)
|
test edi,3 // is string aligned on dword (4 bytes)
|
||||||
push ebx ; preserve ebx
|
push ebx // preserve ebx
|
||||||
je short find_end_of_front_string_loop
|
je short find_end_of_front_string_loop
|
||||||
|
|
||||||
; simple byte loop until string is aligned
|
// simple byte loop until string is aligned
|
||||||
|
|
||||||
front_misaligned:
|
front_misaligned:
|
||||||
mov al,byte ptr [edi]
|
mov al,byte ptr [edi]
|
||||||
|
@ -90,27 +93,27 @@ front_misaligned:
|
||||||
jne short front_misaligned
|
jne short front_misaligned
|
||||||
|
|
||||||
find_end_of_front_string_loop:
|
find_end_of_front_string_loop:
|
||||||
mov eax,dword ptr [edi] ; read dword (4 bytes)
|
mov eax,dword ptr [edi] // read dword (4 bytes)
|
||||||
mov edx,7efefeffh
|
mov edx,HEX(7efefeff)
|
||||||
add edx,eax
|
add edx,eax
|
||||||
xor eax,-1
|
xor eax,-1
|
||||||
xor eax,edx
|
xor eax,edx
|
||||||
add edi,4
|
add edi,4
|
||||||
test eax,81010100h
|
test eax,HEX(81010100)
|
||||||
je short find_end_of_front_string_loop
|
je short find_end_of_front_string_loop
|
||||||
|
|
||||||
; found zero byte in the loop
|
// found zero byte in the loop
|
||||||
mov eax,[edi - 4]
|
mov eax,[edi - 4]
|
||||||
test al,al ; is it byte 0
|
test al,al // is it byte 0
|
||||||
je short start_byte_0
|
je short start_byte_0
|
||||||
test ah,ah ; is it byte 1
|
test ah,ah // is it byte 1
|
||||||
je short start_byte_1
|
je short start_byte_1
|
||||||
test eax,00ff0000h ; is it byte 2
|
test eax,HEX(00ff0000) // is it byte 2
|
||||||
je short start_byte_2
|
je short start_byte_2
|
||||||
test eax,0ff000000h ; is it byte 3
|
test eax,HEX(0ff000000) // is it byte 3
|
||||||
jne short find_end_of_front_string_loop
|
jne short find_end_of_front_string_loop
|
||||||
; taken if bits 24-30 are clear and bit
|
// taken if bits 24-30 are clear and bit
|
||||||
; 31 is set
|
// 31 is set
|
||||||
start_byte_3:
|
start_byte_3:
|
||||||
sub edi,1
|
sub edi,1
|
||||||
jmp short copy_start
|
jmp short copy_start
|
||||||
|
@ -123,20 +126,20 @@ start_byte_1:
|
||||||
start_byte_0:
|
start_byte_0:
|
||||||
sub edi,4
|
sub edi,4
|
||||||
|
|
||||||
; edi now points to the end of front string.
|
// edi now points to the end of front string.
|
||||||
|
|
||||||
copy_start:
|
copy_start:
|
||||||
mov esi,[esp + 14h] ; esi -> back string
|
mov esi,[esp + HEX(14)] // esi -> back string
|
||||||
test esi,3 ; is back string is dword aligned?
|
test esi,3 // is back string is dword aligned?
|
||||||
jnz back_misaligned
|
jnz back_misaligned
|
||||||
|
|
||||||
mov ebx,ecx ; store count for tail loop
|
mov ebx,ecx // store count for tail loop
|
||||||
|
|
||||||
shr ecx,2
|
shr ecx,2
|
||||||
jnz short main_loop_entrance
|
jnz short main_loop_entrance
|
||||||
jmp short tail_loop_start ; 0 < counter < 4
|
jmp short tail_loop_start // 0 < counter < 4
|
||||||
|
|
||||||
; simple byte loop until back string is aligned
|
// simple byte loop until back string is aligned
|
||||||
|
|
||||||
back_misaligned:
|
back_misaligned:
|
||||||
mov dl,byte ptr [esi]
|
mov dl,byte ptr [esi]
|
||||||
|
@ -149,14 +152,14 @@ back_misaligned:
|
||||||
jz empty_counter
|
jz empty_counter
|
||||||
test esi,3
|
test esi,3
|
||||||
jne short back_misaligned
|
jne short back_misaligned
|
||||||
mov ebx,ecx ; store count for tail loop
|
mov ebx,ecx // store count for tail loop
|
||||||
shr ecx,2 ; convert ecx to dword count
|
shr ecx,2 // convert ecx to dword count
|
||||||
jnz short main_loop_entrance
|
jnz short main_loop_entrance
|
||||||
|
|
||||||
tail_loop_start:
|
tail_loop_start:
|
||||||
mov ecx,ebx
|
mov ecx,ebx
|
||||||
and ecx,3 ; ecx = count of leftover bytes after the
|
and ecx,3 // ecx = count of leftover bytes after the
|
||||||
; dwords have been concatenated
|
// dwords have been concatenated
|
||||||
jz empty_counter
|
jz empty_counter
|
||||||
|
|
||||||
tail_loop:
|
tail_loop:
|
||||||
|
@ -165,88 +168,88 @@ tail_loop:
|
||||||
mov [edi],dl
|
mov [edi],dl
|
||||||
add edi,1
|
add edi,1
|
||||||
test dl,dl
|
test dl,dl
|
||||||
je short finish1 ; '\0' was already copied
|
je short finish1 // '\0' was already copied
|
||||||
sub ecx,1
|
sub ecx,1
|
||||||
jnz tail_loop
|
jnz tail_loop
|
||||||
|
|
||||||
empty_counter:
|
empty_counter:
|
||||||
mov [edi],cl ; cl=0;
|
mov [edi],cl // cl=0;
|
||||||
finish1:
|
finish1:
|
||||||
pop ebx
|
pop ebx
|
||||||
pop esi
|
pop esi
|
||||||
finish:
|
finish:
|
||||||
mov eax,[esp + 8] ; return in eax pointer to front string
|
mov eax,[esp + 8] // return in eax pointer to front string
|
||||||
pop edi
|
pop edi
|
||||||
ret ; _cdecl return
|
ret // _cdecl return
|
||||||
|
|
||||||
|
|
||||||
byte_0:
|
byte_0:
|
||||||
mov [edi],dl
|
mov [edi],dl
|
||||||
mov eax,[esp + 10h] ; return in eax pointer to front string
|
mov eax,[esp + HEX(10)] // return in eax pointer to front string
|
||||||
pop ebx
|
pop ebx
|
||||||
pop esi
|
pop esi
|
||||||
pop edi
|
pop edi
|
||||||
ret ; _cdecl return
|
ret // _cdecl return
|
||||||
|
|
||||||
|
|
||||||
main_loop: ; edx contains first dword of back string
|
main_loop: // edx contains first dword of back string
|
||||||
mov [edi],edx ; store one more dword
|
mov [edi],edx // store one more dword
|
||||||
add edi,4 ; kick pointer to front string
|
add edi,4 // kick pointer to front string
|
||||||
|
|
||||||
sub ecx,1
|
sub ecx,1
|
||||||
jz tail_loop_start
|
jz tail_loop_start
|
||||||
main_loop_entrance:
|
main_loop_entrance:
|
||||||
mov edx,7efefeffh
|
mov edx,HEX(7efefeff)
|
||||||
mov eax,dword ptr [esi] ; read 4 bytes
|
mov eax,dword ptr [esi] // read 4 bytes
|
||||||
|
|
||||||
add edx,eax
|
add edx,eax
|
||||||
xor eax,-1
|
xor eax,-1
|
||||||
|
|
||||||
xor eax,edx
|
xor eax,edx
|
||||||
mov edx,[esi] ; it's in cache now
|
mov edx,[esi] // it's in cache now
|
||||||
|
|
||||||
add esi,4 ; kick pointer to back string
|
add esi,4 // kick pointer to back string
|
||||||
test eax,81010100h
|
test eax,HEX(81010100)
|
||||||
|
|
||||||
je short main_loop
|
je short main_loop
|
||||||
|
|
||||||
; may be found zero byte in the loop
|
// may be found zero byte in the loop
|
||||||
test dl,dl ; is it byte 0
|
test dl,dl // is it byte 0
|
||||||
je short byte_0
|
je short byte_0
|
||||||
test dh,dh ; is it byte 1
|
test dh,dh // is it byte 1
|
||||||
je short byte_1
|
je short byte_1
|
||||||
test edx,00ff0000h ; is it byte 2
|
test edx,HEX(00ff0000) // is it byte 2
|
||||||
je short byte_2
|
je short byte_2
|
||||||
test edx,0ff000000h ; is it byte 3
|
test edx,HEX(0ff000000) // is it byte 3
|
||||||
jne short main_loop ; taken if bits 24-30 are clear and bit
|
jne short main_loop // taken if bits 24-30 are clear and bit
|
||||||
; 31 is set
|
// 31 is set
|
||||||
byte_3:
|
byte_3:
|
||||||
mov [edi],edx
|
mov [edi],edx
|
||||||
mov eax,[esp + 10h] ; return in eax pointer to front string
|
mov eax,[esp + HEX(10)] // return in eax pointer to front string
|
||||||
pop ebx
|
pop ebx
|
||||||
pop esi
|
pop esi
|
||||||
pop edi
|
pop edi
|
||||||
ret ; _cdecl return
|
ret // _cdecl return
|
||||||
|
|
||||||
byte_2:
|
byte_2:
|
||||||
mov [edi],dx
|
mov [edi],dx
|
||||||
xor edx,edx
|
xor edx,edx
|
||||||
mov eax,[esp + 10h] ; return in eax pointer to front string
|
mov eax,[esp + HEX(10)] // return in eax pointer to front string
|
||||||
mov [edi + 2],dl
|
mov [edi + 2],dl
|
||||||
pop ebx
|
pop ebx
|
||||||
pop esi
|
pop esi
|
||||||
pop edi
|
pop edi
|
||||||
ret ; _cdecl return
|
ret // _cdecl return
|
||||||
|
|
||||||
byte_1:
|
byte_1:
|
||||||
mov [edi],dx
|
mov [edi],dx
|
||||||
mov eax,[esp + 10h] ; return in eax pointer to front string
|
mov eax,[esp + HEX(10)] // return in eax pointer to front string
|
||||||
pop ebx
|
pop ebx
|
||||||
pop esi
|
pop esi
|
||||||
pop edi
|
pop edi
|
||||||
ret ; _cdecl return
|
ret // _cdecl return
|
||||||
|
|
||||||
strncat endp
|
.ENDP // _strncat
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strncmp.asm - compare two strings
|
title strncmp.asm - compare two strings
|
||||||
;***
|
;***
|
||||||
|
@ -73,43 +75,44 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
CHAR_TYPE EQU BYTE
|
#define CHAR_TYPE BYTE
|
||||||
CHAR_PTR EQU BYTE PTR
|
#define CHAR_PTR BYTE PTR
|
||||||
CHAR_SIZE = sizeof CHAR_TYPE
|
#define CHAR_SIZE 1 // = sizeof CHAR_TYPE
|
||||||
|
|
||||||
BLK_TYPE EQU DWORD
|
#define BLK_TYPE DWORD
|
||||||
BLK_PTR EQU DWORD PTR
|
#define BLK_PTR DWORD PTR
|
||||||
BLK_SIZE = sizeof BLK_TYPE
|
#define BLK_SIZE 4 // = sizeof BLK_TYPE
|
||||||
BLK_CHARS = BLK_SIZE / CHAR_SIZE
|
#define BLK_CHARS 4 // = BLK_SIZE / CHAR_SIZE
|
||||||
|
|
||||||
PAGE_SIZE = 1000h
|
PAGE_SIZE = HEX(1000)
|
||||||
PAGE_MASK = PAGE_SIZE - 1 ; mask for offset in MM page
|
PAGE_MASK = PAGE_SIZE - 1 // mask for offset in MM page
|
||||||
PAGE_SAFE_BLK = PAGE_SIZE - BLK_SIZE ; maximum offset for safe block compare
|
PAGE_SAFE_BLK = PAGE_SIZE - BLK_SIZE // maximum offset for safe block compare
|
||||||
|
|
||||||
public strncmp
|
public _strncmp
|
||||||
strncmp proc \
|
.PROC _strncmp
|
||||||
uses ebx esi, \
|
// uses ebx esi, \
|
||||||
str1:ptr byte, \
|
// str1:ptr byte, \
|
||||||
str2:ptr byte, \
|
// str2:ptr byte, \
|
||||||
count:IWORD
|
// count:IWORD
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
push ebx
|
push ebx
|
||||||
push esi
|
push esi
|
||||||
|
|
||||||
; .FPO (cdwLocals, cdwParams, cbProlog, cbRegs, fUseBP, cbFrame)
|
// .FPO (cdwLocals, cdwParams, cbProlog, cbRegs, fUseBP, cbFrame)
|
||||||
.FPO ( 0, 3, $ - strncmp, 2, 0, 0 )
|
FPO 0, 3, ($ - _strncmp), 2, 0, 0
|
||||||
|
|
||||||
mov ecx,[esp + 12] ; ecx = str1
|
mov ecx,[esp + 12] // ecx = str1
|
||||||
mov edx,[esp + 16] ; edx = str2
|
mov edx,[esp + 16] // edx = str2
|
||||||
mov ebx,[esp + 20] ; ebx = count
|
mov ebx,[esp + 20] // ebx = count
|
||||||
|
|
||||||
; Check for a limit of zero characters.
|
// Check for a limit of zero characters.
|
||||||
test ebx, 0FFFFFFFFh
|
test ebx, HEX(0FFFFFFFF)
|
||||||
jz return_equal
|
jz return_equal
|
||||||
|
|
||||||
sub ecx, edx
|
sub ecx, edx
|
||||||
|
@ -146,11 +149,11 @@ dword_loop_begin:
|
||||||
sub ebx, BLK_CHARS
|
sub ebx, BLK_CHARS
|
||||||
jbe return_equal
|
jbe return_equal
|
||||||
|
|
||||||
lea esi, [eax+0fefefeffh]
|
lea esi, [eax+HEX(0fefefeff)]
|
||||||
add edx, BLK_SIZE
|
add edx, BLK_SIZE
|
||||||
not eax
|
not eax
|
||||||
and eax, esi
|
and eax, esi
|
||||||
test eax, 80808080h
|
test eax, HEX(80808080)
|
||||||
jz dword_loop_begin
|
jz dword_loop_begin
|
||||||
|
|
||||||
return_equal:
|
return_equal:
|
||||||
|
@ -162,12 +165,12 @@ return_equal:
|
||||||
align 16
|
align 16
|
||||||
|
|
||||||
return_not_equal:
|
return_not_equal:
|
||||||
sbb eax, eax ; AX=-1, CY=1 AX=0, CY=0
|
sbb eax, eax // AX=-1, CY=1 AX=0, CY=0
|
||||||
or eax, 1
|
or eax, 1
|
||||||
pop esi
|
pop esi
|
||||||
pop ebx
|
pop ebx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
strncmp endp
|
.ENDP // _strncmp
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strncpy - copy at most n characters of string
|
title strncpy - copy at most n characters of string
|
||||||
;***
|
;***
|
||||||
|
@ -55,95 +57,96 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
public strncpy
|
public _strncpy
|
||||||
strncpy proc \
|
.PROC _strncpy
|
||||||
dest:ptr byte, \
|
// dest:ptr byte, \
|
||||||
source:ptr byte, \
|
// source:ptr byte, \
|
||||||
count:dword
|
// count:dword
|
||||||
|
|
||||||
OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
//OPTION PROLOGUE:NONE, EPILOGUE:NONE
|
||||||
|
|
||||||
.FPO ( 0, 3, 0, 0, 0, 0 )
|
FPO 0, 3, 0, 0, 0, 0
|
||||||
|
|
||||||
mov ecx,[esp + 0ch] ; ecx = count
|
mov ecx,[esp + HEX(0c)] // ecx = count
|
||||||
push edi ; preserve edi
|
push edi // preserve edi
|
||||||
test ecx,ecx
|
test ecx,ecx
|
||||||
jz finish ; leave if count is zero
|
jz finish // leave if count is zero
|
||||||
|
|
||||||
push esi ; preserve edi
|
push esi // preserve edi
|
||||||
push ebx ; preserve ebx
|
push ebx // preserve ebx
|
||||||
mov ebx,ecx ; store count for tail loop
|
mov ebx,ecx // store count for tail loop
|
||||||
mov esi,[esp + 14h] ; esi -> source string
|
mov esi,[esp + HEX(14)] // esi -> source string
|
||||||
test esi,3 ; test if source string is aligned on 32 bits
|
test esi,3 // test if source string is aligned on 32 bits
|
||||||
mov edi,[esp + 10h] ; edi -> dest string
|
mov edi,[esp + HEX(10)] // edi -> dest string
|
||||||
jnz short src_misaligned ; (almost always source is aligned)
|
jnz short src_misaligned // (almost always source is aligned)
|
||||||
|
|
||||||
shr ecx,2 ; convert ecx to dword count
|
shr ecx,2 // convert ecx to dword count
|
||||||
jnz main_loop_entrance
|
jnz main_loop_entrance
|
||||||
jmp short copy_tail_loop ; 0 < count < 4
|
jmp short copy_tail_loop // 0 < count < 4
|
||||||
|
|
||||||
; simple byte loop until string is aligned
|
// simple byte loop until string is aligned
|
||||||
|
|
||||||
src_misaligned:
|
src_misaligned:
|
||||||
mov al,byte ptr [esi] ; copy a byte from source to dest
|
mov al,byte ptr [esi] // copy a byte from source to dest
|
||||||
add esi,1
|
add esi,1
|
||||||
mov [edi],al
|
mov [edi],al
|
||||||
add edi,1
|
add edi,1
|
||||||
sub ecx,1
|
sub ecx,1
|
||||||
jz fill_tail_end1 ; if count == 0, leave
|
jz fill_tail_end1 // if count == 0, leave
|
||||||
test al,al ; was last copied byte zero?
|
test al,al // was last copied byte zero?
|
||||||
jz short align_dest ; if so, go align dest and pad it out
|
jz short align_dest // if so, go align dest and pad it out
|
||||||
; with zeros
|
// with zeros
|
||||||
test esi,3 ; esi already aligned ?
|
test esi,3 // esi already aligned ?
|
||||||
jne short src_misaligned
|
jne short src_misaligned
|
||||||
mov ebx,ecx ; store count for tail loop
|
mov ebx,ecx // store count for tail loop
|
||||||
shr ecx,2
|
shr ecx,2
|
||||||
jnz short main_loop_entrance
|
jnz short main_loop_entrance
|
||||||
|
|
||||||
tail_loop_start:
|
tail_loop_start:
|
||||||
and ebx,3 ; ebx = count_before_main_loop%4
|
and ebx,3 // ebx = count_before_main_loop%4
|
||||||
jz short fill_tail_end1 ; if ebx == 0 then leave without
|
jz short fill_tail_end1 // if ebx == 0 then leave without
|
||||||
; appending a null byte
|
// appending a null byte
|
||||||
|
|
||||||
; while ( EOS (end-of-string) not found and count > 0 ) copy bytes
|
// while ( EOS (end-of-string) not found and count > 0 ) copy bytes
|
||||||
|
|
||||||
copy_tail_loop:
|
copy_tail_loop:
|
||||||
mov al,byte ptr [esi] ; load byte from source
|
mov al,byte ptr [esi] // load byte from source
|
||||||
add esi,1
|
add esi,1
|
||||||
mov [edi],al ; store byte to dest
|
mov [edi],al // store byte to dest
|
||||||
add edi,1
|
add edi,1
|
||||||
test al,al ; EOS found?
|
test al,al // EOS found?
|
||||||
je short fill_tail_zero_bytes ; '\0' was already copied
|
je short fill_tail_zero_bytes // '\0' was already copied
|
||||||
sub ebx,1
|
sub ebx,1
|
||||||
jnz copy_tail_loop
|
jnz copy_tail_loop
|
||||||
fill_tail_end1:
|
fill_tail_end1:
|
||||||
mov eax,[esp + 10h] ; prepare return value
|
mov eax,[esp + HEX(10)] // prepare return value
|
||||||
pop ebx
|
pop ebx
|
||||||
pop esi
|
pop esi
|
||||||
pop edi
|
pop edi
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; EOS found. Pad with null characters to length count
|
// EOS found. Pad with null characters to length count
|
||||||
|
|
||||||
align_dest:
|
align_dest:
|
||||||
test edi,3 ; dest string aligned?
|
test edi,3 // dest string aligned?
|
||||||
jz dest_align_loop_end
|
jz dest_align_loop_end
|
||||||
dest_align_loop:
|
dest_align_loop:
|
||||||
mov [edi],al
|
mov [edi],al
|
||||||
add edi,1
|
add edi,1
|
||||||
sub ecx,1 ; count == 0?
|
sub ecx,1 // count == 0?
|
||||||
jz fill_tail_end ; if so, finished
|
jz fill_tail_end // if so, finished
|
||||||
test edi,3 ; is edi aligned ?
|
test edi,3 // is edi aligned ?
|
||||||
jnz dest_align_loop
|
jnz dest_align_loop
|
||||||
dest_align_loop_end:
|
dest_align_loop_end:
|
||||||
mov ebx,ecx ; ebx > 0
|
mov ebx,ecx // ebx > 0
|
||||||
shr ecx,2 ; convert ecx to count of dwords
|
shr ecx,2 // convert ecx to count of dwords
|
||||||
jnz fill_dwords_with_EOS
|
jnz fill_dwords_with_EOS
|
||||||
; pad tail bytes
|
// pad tail bytes
|
||||||
finish_loop: ; 0 < ebx < 4
|
finish_loop: // 0 < ebx < 4
|
||||||
mov [edi],al
|
mov [edi],al
|
||||||
add edi,1
|
add edi,1
|
||||||
fill_tail_zero_bytes:
|
fill_tail_zero_bytes:
|
||||||
|
@ -152,68 +155,68 @@ fill_tail_zero_bytes:
|
||||||
pop ebx
|
pop ebx
|
||||||
pop esi
|
pop esi
|
||||||
finish:
|
finish:
|
||||||
mov eax,[esp + 8] ; return in eax pointer to dest string
|
mov eax,[esp + 8] // return in eax pointer to dest string
|
||||||
pop edi
|
pop edi
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; copy (source) string to (dest). Also look for end of (source) string
|
// copy (source) string to (dest). Also look for end of (source) string
|
||||||
|
|
||||||
main_loop: ; edx contains first dword of source string
|
main_loop: // edx contains first dword of source string
|
||||||
mov [edi],edx ; store one more dword
|
mov [edi],edx // store one more dword
|
||||||
add edi,4 ; kick dest pointer
|
add edi,4 // kick dest pointer
|
||||||
sub ecx,1
|
sub ecx,1
|
||||||
jz tail_loop_start
|
jz tail_loop_start
|
||||||
|
|
||||||
main_loop_entrance:
|
main_loop_entrance:
|
||||||
mov edx,7efefeffh
|
mov edx,HEX(7efefeff)
|
||||||
mov eax,dword ptr [esi] ; read 4 bytes (dword)
|
mov eax,dword ptr [esi] // read 4 bytes (dword)
|
||||||
add edx,eax
|
add edx,eax
|
||||||
xor eax,-1
|
xor eax,-1
|
||||||
xor eax,edx
|
xor eax,edx
|
||||||
mov edx,[esi] ; it's in cache now
|
mov edx,[esi] // it's in cache now
|
||||||
add esi,4 ; kick dest pointer
|
add esi,4 // kick dest pointer
|
||||||
test eax,81010100h
|
test eax,HEX(81010100)
|
||||||
je short main_loop
|
je short main_loop
|
||||||
|
|
||||||
; may have found zero byte in the dword
|
// may have found zero byte in the dword
|
||||||
|
|
||||||
test dl,dl ; is it byte 0
|
test dl,dl // is it byte 0
|
||||||
je short byte_0
|
je short byte_0
|
||||||
test dh,dh ; is it byte 1
|
test dh,dh // is it byte 1
|
||||||
je short byte_1
|
je short byte_1
|
||||||
test edx,00ff0000h ; is it byte 2
|
test edx,HEX(00ff0000) // is it byte 2
|
||||||
je short byte_2
|
je short byte_2
|
||||||
test edx,0ff000000h ; is it byte 3
|
test edx,HEX(0ff000000) // is it byte 3
|
||||||
jne short main_loop ; taken if bits 24-30 are clear and bit
|
jne short main_loop // taken if bits 24-30 are clear and bit
|
||||||
; 31 is set
|
// 31 is set
|
||||||
|
|
||||||
; a null character was found, so dest needs to be padded out with null chars
|
// a null character was found, so dest needs to be padded out with null chars
|
||||||
; to count length.
|
// to count length.
|
||||||
|
|
||||||
mov [edi],edx
|
mov [edi],edx
|
||||||
jmp short fill_with_EOS_dwords
|
jmp short fill_with_EOS_dwords
|
||||||
|
|
||||||
byte_2:
|
byte_2:
|
||||||
and edx,0ffffh ; fill high 2 bytes with 0
|
and edx,HEX(0ffff) // fill high 2 bytes with 0
|
||||||
mov [edi],edx
|
mov [edi],edx
|
||||||
jmp short fill_with_EOS_dwords
|
jmp short fill_with_EOS_dwords
|
||||||
|
|
||||||
byte_1:
|
byte_1:
|
||||||
and edx,0ffh ; fill high 3 bytes with 0
|
and edx,HEX(0ff) // fill high 3 bytes with 0
|
||||||
mov [edi],edx
|
mov [edi],edx
|
||||||
jmp short fill_with_EOS_dwords
|
jmp short fill_with_EOS_dwords
|
||||||
|
|
||||||
byte_0:
|
byte_0:
|
||||||
xor edx,edx ; fill whole dword with 0
|
xor edx,edx // fill whole dword with 0
|
||||||
mov [edi],edx
|
mov [edi],edx
|
||||||
|
|
||||||
; End of string was found. Pad out dest string with dwords of 0
|
// End of string was found. Pad out dest string with dwords of 0
|
||||||
|
|
||||||
fill_with_EOS_dwords: ; ecx > 0 (ecx is dword counter)
|
fill_with_EOS_dwords: // ecx > 0 (ecx is dword counter)
|
||||||
add edi,4
|
add edi,4
|
||||||
xor eax,eax ; it is instead of ???????????????????
|
xor eax,eax // it is instead of ???????????????????
|
||||||
sub ecx,1
|
sub ecx,1
|
||||||
jz fill_tail ; we filled all dwords
|
jz fill_tail // we filled all dwords
|
||||||
|
|
||||||
fill_dwords_with_EOS:
|
fill_dwords_with_EOS:
|
||||||
xor eax,eax
|
xor eax,eax
|
||||||
|
@ -222,17 +225,17 @@ fill_with_EOS_loop:
|
||||||
add edi,4
|
add edi,4
|
||||||
sub ecx,1
|
sub ecx,1
|
||||||
jnz short fill_with_EOS_loop
|
jnz short fill_with_EOS_loop
|
||||||
fill_tail: ; let's pad tail bytes with zero
|
fill_tail: // let's pad tail bytes with zero
|
||||||
and ebx,3 ; ebx = ebx % 4
|
and ebx,3 // ebx = ebx % 4
|
||||||
jnz finish_loop ; taken, when there are some tail bytes
|
jnz finish_loop // taken, when there are some tail bytes
|
||||||
fill_tail_end:
|
fill_tail_end:
|
||||||
mov eax,[esp + 10h]
|
mov eax,[esp + HEX(10)]
|
||||||
pop ebx
|
pop ebx
|
||||||
pop esi
|
pop esi
|
||||||
pop edi
|
pop edi
|
||||||
ret
|
ret
|
||||||
|
|
||||||
strncpy endp
|
.ENDP // _strncpy
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strnset - set first n characters to one char.
|
title strnset - set first n characters to one char.
|
||||||
;***
|
;***
|
||||||
|
@ -50,40 +52,49 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
public _strnset
|
public __strnset
|
||||||
_strnset proc \
|
.PROC __strnset
|
||||||
uses edi ebx, \
|
// Prolog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
string:ptr byte, \
|
push ebp
|
||||||
val:byte, \
|
mov ebp, esp
|
||||||
count:IWORD
|
push edi // uses edi ebx
|
||||||
|
push ebx
|
||||||
|
#define string ebp + 8 // string:ptr byte
|
||||||
|
#define val ebp + 12 // val:byte
|
||||||
|
#define count ebp + 16 // count:IWORD
|
||||||
|
|
||||||
|
|
||||||
mov edi,[string] ; di = string
|
mov edi,[string] // di = string
|
||||||
mov edx,edi ; dx=string addr; save return value
|
mov edx,edi // dx=string addr; save return value
|
||||||
mov ebx,[count] ; cx = max chars to set
|
mov ebx,[count] // cx = max chars to set
|
||||||
xor eax,eax ; null byte
|
xor eax,eax // null byte
|
||||||
mov ecx,ebx
|
mov ecx,ebx
|
||||||
jecxz short done ; zero length specified
|
jecxz short done // zero length specified
|
||||||
|
|
||||||
repne scasb ; find null byte & count bytes in cx
|
repne scasb // find null byte & count bytes in cx
|
||||||
jne short nonull ; null not found
|
jne short nonull // null not found
|
||||||
add ecx,1 ; don't want the null
|
add ecx,1 // don't want the null
|
||||||
|
|
||||||
nonull:
|
nonull:
|
||||||
sub ebx,ecx ; bx=strlen (not null)
|
sub ebx,ecx // bx=strlen (not null)
|
||||||
mov ecx,ebx ; cx=strlen (not null)
|
mov ecx,ebx // cx=strlen (not null)
|
||||||
|
|
||||||
mov edi,edx ; restore string pointer
|
mov edi,edx // restore string pointer
|
||||||
mov al,val ; byte value
|
mov al,[val] // byte value
|
||||||
rep stosb ; fill 'er up
|
rep stosb // fill 'er up
|
||||||
|
|
||||||
done:
|
done:
|
||||||
mov eax,edx ; return value: string addr
|
mov eax,edx // return value: string addr
|
||||||
|
|
||||||
ret ; _cdecl return
|
// Epilog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
|
pop ebx
|
||||||
|
pop edi
|
||||||
|
pop ebp
|
||||||
|
ret // _cdecl return
|
||||||
|
|
||||||
_strnset endp
|
.ENDP // __strnset
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#if 0
|
||||||
;***
|
;***
|
||||||
;strpbrk.asm -
|
;strpbrk.asm -
|
||||||
;
|
;
|
||||||
|
@ -14,3 +15,7 @@
|
||||||
|
|
||||||
SSTRPBRK EQU 1
|
SSTRPBRK EQU 1
|
||||||
INCLUDE STRSPN.ASM
|
INCLUDE STRSPN.ASM
|
||||||
|
#else
|
||||||
|
#define SSTRPBRK 1
|
||||||
|
#include "strspn.s"
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strrev - reverse a string in place
|
title strrev - reverse a string in place
|
||||||
;***
|
;***
|
||||||
|
@ -63,43 +65,52 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
public _strrev
|
public __strrev
|
||||||
_strrev proc \
|
.PROC __strrev
|
||||||
uses edi esi, \
|
// Prolog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
string:ptr byte
|
push ebp
|
||||||
|
mov ebp, esp
|
||||||
|
push edi // uses edi esi
|
||||||
|
push esi
|
||||||
|
#define string ebp + 8 // string:ptr byte
|
||||||
|
|
||||||
mov edi,[string] ; di = string
|
mov edi,[string] // di = string
|
||||||
mov edx,edi ; dx=pointer to string; save return value
|
mov edx,edi // dx=pointer to string; save return value
|
||||||
|
|
||||||
mov esi,edi ; si=pointer to string
|
mov esi,edi // si=pointer to string
|
||||||
xor eax,eax ; search value (null)
|
xor eax,eax // search value (null)
|
||||||
or ecx,-1 ; cx = -1
|
or ecx,-1 // cx = -1
|
||||||
repne scasb ; find null
|
repne scasb // find null
|
||||||
cmp ecx,-2 ; is string empty? (if offset value is 0, the
|
cmp ecx,-2 // is string empty? (if offset value is 0, the
|
||||||
je short done ; cmp below will not catch it and we'll hang).
|
je short done // cmp below will not catch it and we'll hang).
|
||||||
|
|
||||||
sub edi,2 ; string is not empty, move di pointer back
|
sub edi,2 // string is not empty, move di pointer back
|
||||||
; di points to last non-null byte
|
// di points to last non-null byte
|
||||||
|
|
||||||
lupe:
|
lupe:
|
||||||
cmp esi,edi ; see if pointers have crossed yet
|
cmp esi,edi // see if pointers have crossed yet
|
||||||
jae short done ; exit when pointers meet (or cross)
|
jae short done // exit when pointers meet (or cross)
|
||||||
|
|
||||||
mov ah,[esi] ; get front byte...
|
mov ah,[esi] // get front byte...
|
||||||
mov al,[edi] ; and end byte
|
mov al,[edi] // and end byte
|
||||||
mov [esi],al ; put end byte in front...
|
mov [esi],al // put end byte in front...
|
||||||
mov [edi],ah ; and front byte at end
|
mov [edi],ah // and front byte at end
|
||||||
add esi,1 ; front moves up...
|
add esi,1 // front moves up...
|
||||||
sub edi,1 ; and end moves down
|
sub edi,1 // and end moves down
|
||||||
jmp short lupe ; keep switching bytes
|
jmp short lupe // keep switching bytes
|
||||||
|
|
||||||
done:
|
done:
|
||||||
mov eax,edx ; return value: string addr
|
mov eax,edx // return value: string addr
|
||||||
|
|
||||||
ret ; _cdecl return
|
// Epilog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
|
pop esi
|
||||||
|
pop edi
|
||||||
|
pop ebp
|
||||||
|
ret // _cdecl return
|
||||||
|
|
||||||
_strrev endp
|
.ENDP // __strrev
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strset - set all characters of string to character
|
title strset - set all characters of string to character
|
||||||
;***
|
;***
|
||||||
|
@ -48,31 +50,39 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
public _strset
|
public __strset
|
||||||
_strset proc \
|
.PROC __strset
|
||||||
uses edi, \
|
// Prolog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
string:ptr byte, \
|
push ebp
|
||||||
val:byte
|
mov ebp, esp
|
||||||
|
push edi // uses edi
|
||||||
|
#define string ebp + 8 // string:ptr byte
|
||||||
|
#define val ebp + 12 // val:byte
|
||||||
|
|
||||||
|
|
||||||
mov edi,[string] ; di = string
|
mov edi,[string] // di = string
|
||||||
mov edx,edi ; dx=string addr; save return value
|
mov edx,edi // dx=string addr; save return value
|
||||||
|
|
||||||
xor eax,eax ; ax = 0
|
xor eax,eax // ax = 0
|
||||||
or ecx,-1 ; cx = -1
|
or ecx,-1 // cx = -1
|
||||||
repne scasb ; scan string & count bytes
|
repne scasb // scan string & count bytes
|
||||||
add ecx,2 ; cx=-strlen
|
add ecx,2 // cx=-strlen
|
||||||
neg ecx ; cx=strlen
|
neg ecx // cx=strlen
|
||||||
mov al,[val] ; al = byte value to store
|
mov al,[val] // al = byte value to store
|
||||||
mov edi,edx ; di=string addr
|
mov edi,edx // di=string addr
|
||||||
rep stosb
|
rep stosb
|
||||||
|
|
||||||
mov eax,edx ; return value: string addr
|
mov eax,edx // return value: string addr
|
||||||
|
|
||||||
ret ; _cdecl return
|
// Epilog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
|
pop edi
|
||||||
|
pop ebp
|
||||||
|
|
||||||
_strset endp
|
ret // _cdecl return
|
||||||
|
|
||||||
|
.ENDP // __strset
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <asm.inc>
|
||||||
|
#if 0
|
||||||
page ,132
|
page ,132
|
||||||
title strspn - search for init substring of chars from control str
|
title strspn - search for init substring of chars from control str
|
||||||
;***
|
;***
|
||||||
|
@ -165,54 +167,58 @@ page
|
||||||
;Exceptions:
|
;Exceptions:
|
||||||
;
|
;
|
||||||
;*******************************************************************************
|
;*******************************************************************************
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ifdef SSTRCSPN
|
#ifdef SSTRCSPN
|
||||||
|
|
||||||
_STRSPN_ equ <strcspn>
|
#define _STRSPN_ _strcspn
|
||||||
|
|
||||||
elseifdef SSTRPBRK
|
#elif defined(SSTRPBRK)
|
||||||
|
|
||||||
_STRSPN_ equ <strpbrk>
|
#define _STRSPN_ _strpbrk
|
||||||
|
|
||||||
else ; SSTRCSPN
|
#else // SSTRCSPN
|
||||||
|
|
||||||
; Default is to build strspn()
|
// Default is to build strspn()
|
||||||
|
|
||||||
SSTRSPN equ 1
|
#define SSTRSPN 1
|
||||||
_STRSPN_ equ <strspn>
|
#define _STRSPN_ _strspn
|
||||||
|
|
||||||
endif ; SSTRCSPN
|
#endif // SSTRCSPN
|
||||||
|
|
||||||
% public _STRSPN_
|
public _STRSPN_
|
||||||
|
|
||||||
CODESEG
|
.code
|
||||||
|
|
||||||
_STRSPN_ proc \
|
.PROC _STRSPN_
|
||||||
uses esi, \
|
// Prolog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
string:ptr byte, \
|
push ebp
|
||||||
control:ptr byte
|
mov ebp, esp
|
||||||
|
push esi // uses esi
|
||||||
|
#define string ebp + 8 // string:ptr byte
|
||||||
|
#define control ebp + 12 // control:ptr byte
|
||||||
|
|
||||||
; create and zero out char bit map
|
// create and zero out char bit map
|
||||||
|
|
||||||
xor eax,eax
|
xor eax,eax
|
||||||
push eax ; 32
|
push eax // 32
|
||||||
push eax
|
push eax
|
||||||
push eax
|
push eax
|
||||||
push eax ; 128
|
push eax // 128
|
||||||
push eax
|
push eax
|
||||||
push eax
|
push eax
|
||||||
push eax
|
push eax
|
||||||
push eax ; 256
|
push eax // 256
|
||||||
|
|
||||||
map equ [esp]
|
#define map [esp]
|
||||||
|
|
||||||
; Set control char bits in map
|
// Set control char bits in map
|
||||||
|
|
||||||
mov edx,control ; si = control string
|
mov edx,[control] // si = control string
|
||||||
|
|
||||||
align @WordSize
|
align 4 // @WordSize
|
||||||
lab listnext ; init char bit map
|
listnext: // init char bit map
|
||||||
mov al,[edx]
|
mov al,[edx]
|
||||||
or al,al
|
or al,al
|
||||||
jz short listdone
|
jz short listdone
|
||||||
|
@ -220,18 +226,22 @@ lab listnext ; init char bit map
|
||||||
bts map,eax
|
bts map,eax
|
||||||
jmp short listnext
|
jmp short listnext
|
||||||
|
|
||||||
lab listdone
|
listdone:
|
||||||
|
|
||||||
; Loop through comparing source string with control bits
|
// Loop through comparing source string with control bits
|
||||||
|
|
||||||
mov esi,string ; si = string
|
mov esi,[string] // si = string
|
||||||
|
|
||||||
_ifnd SSTRPBRK, <or ecx,-1> ; set ecx to -1
|
#ifndef SSTRPBRK
|
||||||
|
or ecx,-1 // set ecx to -1
|
||||||
|
#endif
|
||||||
|
|
||||||
align @WordSize
|
align 4 // @WordSize
|
||||||
lab dstnext
|
dstnext:
|
||||||
|
|
||||||
_ifnd SSTRPBRK, <add ecx,1>
|
#ifndef SSTRPBRK
|
||||||
|
add ecx,1
|
||||||
|
#endif
|
||||||
|
|
||||||
mov al,[esi]
|
mov al,[esi]
|
||||||
or al,al
|
or al,al
|
||||||
|
@ -239,24 +249,30 @@ _ifnd SSTRPBRK, <add ecx,1>
|
||||||
add esi,1
|
add esi,1
|
||||||
bt map, eax
|
bt map, eax
|
||||||
|
|
||||||
ifdef SSTRSPN
|
#ifdef SSTRSPN
|
||||||
jc short dstnext ; strspn: found char, continue
|
jc short dstnext // strspn: found char, continue
|
||||||
elseifdef SSTRCSPN
|
#elif defined SSTRCSPN
|
||||||
jnc short dstnext ; strcspn: did not find char, continue
|
jnc short dstnext // strcspn: did not find char, continue
|
||||||
elseifdef SSTRPBRK
|
#elif defined SSTRPBRK
|
||||||
jnc short dstnext ; strpbrk: did not find char, continue
|
jnc short dstnext // strpbrk: did not find char, continue
|
||||||
lea eax,[esi - 1] ; found char, return address of it
|
lea eax,[esi - 1] // found char, return address of it
|
||||||
endif ; SSTRSPN
|
#endif // SSTRSPN
|
||||||
|
|
||||||
; Return code
|
// Return code
|
||||||
|
|
||||||
lab dstdone
|
dstdone:
|
||||||
|
|
||||||
_ifnd SSTRPBRK, <mov eax,ecx> ; strspn/strcspn: return index
|
#ifndef SSTRPBRK
|
||||||
|
mov eax,ecx // strspn/strcspn: return index
|
||||||
|
#endif
|
||||||
|
|
||||||
add esp,32
|
add esp,32
|
||||||
|
|
||||||
ret ; _cdecl return
|
// Epilog. Original sources used ML's extended PROC feature to autogenerate this.
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
|
|
||||||
_STRSPN_ endp
|
ret // _cdecl return
|
||||||
|
|
||||||
|
.ENDP // _STRSPN_
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue