My shot at it. It's quite easy once you get some key values in your 'brain cache'.
I'll comment along the code...
Code: Select all
GUIStringGreater: ; function label, not globally declared
push esi ; saves esi on top of stack.
cmp word[esi],'.' ; compares the 2 bytes (little endian) at memory location pointed to by esi
je .less ; current value with 0x002E ({ '.', 0 } string) as you should know, the first
; element in a directory is always '.', and the second is always '..' So if the
; 'esi' string is '.', that means it is "smaller" since nothing goes before that.
; of course, the hard part was maybe to realise this function could be used with
; directory listings
cmp word[esi+32],'.' ; now it makes sense, if the second string (located 32 bytes ahead of the first) is
je .greater ; the first element, AND the first string isn't this very element, then first
; string is "greater".
cmp word[esi],'..' ; now checking second special case for first string...
je .less
cmp word[esi+32],'..' ; and for second string.
je .greater
; now we've tested for the special cases, we're gonna have to make some kind of loop to sort all possible filenames
; we may encounter and tell which is 'greater'
.nextchar ; typical loop label name
cmp byte[esi],0 ; check for end of string. the shortest string is always the 'smallest'
je .less
cmp byte[esi+32],0 ; if the second string is shorter, the first is "greater"
je .greater
mov al,[esi] ; puts charA, currently pointed by esi value, in al register
mov cl,[esi+32] ; puts charB, currently pointed by esi value + 32, in cl register
; this will make comparisons easy
cmp al,'a' ; if charA is under 'a', it's not lowercase
jb .noucase1
cmp al,'z' ; again, not lowercase
ja .noucase1
sub al,'z'-'Z' ; transforms lowercase charA into uppercase - another possible line: "sub al,20h"
; (or 32, if you like decimal)
.noucase1 ; if charA wasn't lowercase, we got here from a jump
cmp cl,'a'
jb .noucase2
cmp cl,'z'
ja .noucase2
sub cl,'z'-'Z'
.noucase2 ; same stuff with charB, obviously we're gonna work with uppercases
cmp al,cl ; the comparison.
jb .less ; 1st string smaller...
ja .greater ; or greater...
inc esi ; if equal, look at next char in both strings...
jmp .nextchar ; and loop !
.less ; if we got here, it means first string is 'smaller'
mov al,0
jmp .skip
.greater ; first string is 'greater'
mov al,1
.skip
pop esi ; restore initial pointer position, at beginning of first string
ret ; AKA 'GTFO'
Overload got it. Directory/filename comparison.
Probably to sort them correctly in load menu box.
Noxious Ninja wrote:Code: Select all
; compares string at esi to edi and returns 1 to al if esi is >, else 0
I don't even see where EDI comes into the picture at all.
Well, it's probably an old comment from an older version, where these lines were present in the beginning:
Then, every time esi+32 is used edi was used.
Setting edi outside the function then comparing [esi] with [edi] could give a more powerful function, since it could compare anything with anything. (this one only compares [esi] with [esi+32])