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