voici les 5 instructions de base pour traitement des chaînes ou des donnée en général
MOVS ES:DI, DS:EI = MOVSB MOVSW MOVSD
LODS AX, DS:SI = LODSB LODSW LODSD
STOS ES:DI, AX = STOSB STOSW STOSD
CMPS DS:SI, ES: DI = CMPSB CMPSW CMPSD
SCAS ES:DI, AX = SCASB SCASW SCASD
exemple :
Code : Tout sélectionner
;***********************************************************************************************************************************************************************************
EnableExplicit
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
Macro asmarch:E:EndMacro
Macro pushsize(s):s:EndMacro
CompilerElse
Macro asmarch:R:EndMacro
Macro pushsize(s):s * 2:EndMacro
CompilerEndIf
Procedure String_RemplaceChar(Source,Destination,CharToFind.w,CharToplace.w,len)
PUSH asmarch#SI asmarch#di asmarch#bx asmarch#dx
MOV asmarch#SI, [p.v_Source+pushsize(16)] ; Source
MOV asmarch#di, [p.v_Destination+pushsize(16)] ; Destination
MOV bx, [p.v_CharToFind+pushsize(16)] ; CharToFind
MOV dx, [p.v_CharToplace+pushsize(16)] ; CharToplace
MOV asmarch#cx, [p.v_len+pushsize(16)] ; len
!._SRlooop:
LODSW ; charger character actuel dans eax
CMP AX, bx
JNE ._SRskip
MOV AX,dx
!._SRskip:
STOSW ; enregistrer eax dans edi
; sauter sur le caractère suivant
LOOP ._SRlooop
POP asmarch#dx asmarch#bx asmarch#di asmarch#SI
EndProcedure
Procedure String_Copy(Source,Destination,len)
PUSH asmarch#SI asmarch#di
MOV asmarch#SI, [p.v_Source+pushsize(8)] ; Source
MOV asmarch#di, [p.v_Destination+pushsize(8)] ; Destination
MOV asmarch#cx, [p.v_len+pushsize(8)] ; len
CLD ; 'clear flags' la lecture ce fait de gauche à droite ou utiliser 'STD' pour droite à gauche
; REP MOVSB copy 1 byte ascii
; REP MOVSD copy 4 byte
REP MOVSW ; copier 'esi' dans 'edi' jusqu'à ce que 'ecx = 0'
POP asmarch#di asmarch#SI
EndProcedure
Procedure String_Compare(Source,Destination,len)
PUSH asmarch#SI asmarch#di
MOV asmarch#SI, [p.v_Source+pushsize(8)] ; Source
MOV asmarch#di, [p.v_Destination+pushsize(8)] ; Destination
MOV asmarch#cx, [p.v_len+pushsize(8)] ; len
XOR asmarch#ax, asmarch#ax
INC asmarch#ax ; eax = 1
CLD ; STD
; REP CMPSB ascii
; REP CMPSD
REP CMPSW ; comparer le texte
JE ._SCequal ; sauter si ecx = 0
XOR asmarch#ax,asmarch#ax ; eax = 0
!._SCequal:
POP asmarch#di asmarch#SI
ProcedureReturn ;ret eax
EndProcedure
Procedure String_FindChar(Source,character.w,len)
PUSH asmarch#di
XOR asmarch#ax, asmarch#ax
MOV asmarch#dI, [p.v_Source+pushsize(4)] ; Source
MOV ax, [p.v_character+pushsize(4)] ; character
; MOV al, byte [esp + 8 + 4] Ascii
MOV asmarch#cx, [p.v_len+pushsize(4)] ; len
CLD ; STD
; SCASB
; SCASD
REPNE SCASW ; chercher texte jusqu'à 'ZF' est mise
JE ._SFequal
XOR asmarch#ax,asmarch#ax
JMP ._SFret
!._SFequal:
MOV asmarch#ax,asmarch#di
!._SFret:
POP asmarch#di
ProcedureReturn ; ret eax
EndProcedure
Procedure String_ByteLength(Source)
MOV asmarch#cx,[p.v_Source] ; Source
MOV asmarch#ax,-2
!._SBloop:
ADD asmarch#ax, 2
CMP word [asmarch#cx + asmarch#ax], 0
JNE ._SBloop
ProcedureReturn
EndProcedure
Procedure String_ByteLength2(Source)
PUSH asmarch#di
MOV asmarch#di, [p.v_Source+pushsize(4)] ; Source
XOR asmarch#ax,asmarch#ax
REPNE SCASW
SUB asmarch#di,2
MOV asmarch#ax,asmarch#di
SUB asmarch#ax,[p.v_Source+pushsize(4)]
POP asmarch#di
ProcedureReturn ; ret eax
EndProcedure
Procedure String_Length(Source)
PUSH asmarch#SI
MOV asmarch#SI, [p.v_Source+pushsize(4)] ; Source
XOR asmarch#cx,asmarch#cx
!._SLBloop:
LODSW
TEST AX,AX
JZ ._SLBendloop
INC asmarch#cx
JMP ._SLBloop
!._SLBendloop:
MOV asmarch#ax,asmarch#cx
POP asmarch#SI
ProcedureReturn ;ret eax
EndProcedure
Procedure __Test()
Protected Source.s = "je pense, donc je suis"
Protected Destination.s = " "
Protected len = Len(Source)
String_RemplaceChar(@Source,@Destination,'j','J',len)
Debug Destination
String_Copy(@Source,@Destination,len)
Debug Destination
Debug String_Compare(@Source,@Destination,len)
Debug String_FindChar(@Source,'d',len)
Debug String_ByteLength(@Source)
Debug String_ByteLength2(@Source)
Debug String_Length(@Source)
EndProcedure
__Test()