im disassembling the old 1989 Borland tool TDSTRIP.EXE that can extract Turbo Debugger information from executables and stumpled over this path-normalizing function
this is the signature im using extern "C" void far maybe_lib_sub_103FC(char far* dest, const char far* src);
i think it is not a __cdecl because the routine seems to cleanup the stack on its own and the calls to the routine do not cleanup the stack
i copied the disassembly and re-assembled it binary equal and calling it from a Borland C++ 5.02, DOS, small memory model, testprogram
the code runs only as expected when i replace the last retf 4 with just retf
and i don't understand why 4 bytes - to my understanding there are 2 far-ptrs pushed onto the stack so wouldn't be 8 more correct? or is that only for local variables stack cleanup, but i can't see any local variables
calling looks like this
cmp word ptr [si+2], 0
jz short loc_13478
; ----
; calling starts
push ds
push word ptr [si+2] ; src
push ss
lea ax, [bp+s1]
push ax
call maybe_lib_sub_103FC
; after call no sp adjust
; ----
lea ax, [bp+var_52]
push ax
lea ax, [bp+s1]
push ax ; s1
call _strcmp
this is the routine
seg000:03FC _maybe_lib_sub_103FC proc far ; CODE XREF: MAYBE_MAIN_sub_133D6+61P
seg000:03FC ; MAYBE_MAIN_sub_133D6+7BP
seg000:03FC
seg000:03FC arg_0 = dword ptr 6
seg000:03FC arg_4 = dword ptr 0Ah
seg000:03FC
seg000:03FC 55 push bp
seg000:03FD 8B EC mov bp, sp
seg000:03FF 1E push ds
seg000:0400 56 push si
seg000:0401 57 push di
seg000:0402 FC cld
seg000:0403 C4 7E 0A les di, [bp+arg_4]
seg000:0406 32 C0 xor al, al
seg000:0408 B9 FF FF mov cx, 0FFFFh
seg000:040B F2 AE repne scasb
seg000:040D F7 D1 not cx
seg000:040F 49 dec cx
seg000:0410 C5 76 0A lds si, [bp+arg_4]
seg000:0413 03 CE add cx, si
seg000:0415 C4 7E 06 les di, [bp+arg_0]
seg000:0418 AD lodsw
seg000:0419 3B F1 cmp si, cx
seg000:041B 77 11 ja short loc_1042E
seg000:041D 80 FC 3A cmp ah, ':'
seg000:0420 75 0C jnz short loc_1042E
seg000:0422 3C 61 cmp al, 61h ; 'a'
seg000:0424 72 12 jb short loc_10438
seg000:0426 3C 7A cmp al, 7Ah ; 'z'
seg000:0428 77 0E ja short loc_10438
seg000:042A 2C 20 sub al, 20h ; ' '
seg000:042C EB 0A jmp short loc_10438
seg000:042E ; ---------------------------------------------------------------------------
seg000:042E
seg000:042E loc_1042E: ; CODE XREF: maybe_lib_sub_103FC+1Fj
seg000:042E ; maybe_lib_sub_103FC+24j
seg000:042E 4E dec si
seg000:042F 4E dec si
seg000:0430 B4 19 mov ah, 19h
seg000:0432 CD 21 int 21h ; DOS - GET DEFAULT DISK NUMBER
seg000:0434 04 41 add al, 41h ; 'A'
seg000:0436 B4 3A mov ah, 3Ah ; ':'
seg000:0438
seg000:0438 loc_10438: ; CODE XREF: maybe_lib_sub_103FC+28j
seg000:0438 ; maybe_lib_sub_103FC+2Cj ...
seg000:0438 AB stosw
seg000:0439 3B F1 cmp si, cx
seg000:043B 74 05 jz short loc_10442
seg000:043D 80 3C 5C cmp byte ptr [si], 5Ch ; '\'
seg000:0440 74 28 jz short loc_1046A
seg000:0442
seg000:0442 loc_10442: ; CODE XREF: maybe_lib_sub_103FC+3Fj
seg000:0442 2C 40 sub al, 40h ; '@'
seg000:0444 8A D0 mov dl, al
seg000:0446 B0 5C mov al, 5Ch ; '\'
seg000:0448 AA stosb
seg000:0449 56 push si
seg000:044A 1E push ds
seg000:044B B4 47 mov ah, 47h ; 'G'
seg000:044D 8B F7 mov si, di
seg000:044F 06 push es
seg000:0450 1F pop ds
seg000:0451 CD 21 int 21h ; DOS - 2+ - GET CURRENT DIRECTORY
seg000:0451 ; DL = drive (0=default, 1=A, etc.)
seg000:0451 ; DS:SI points to 64-byte buffer area
seg000:0453 1F pop ds
seg000:0454 5E pop si
seg000:0455 72 13 jb short loc_1046A
seg000:0457 26 80 3D 00 cmp byte ptr es:[di], 0
seg000:045B 74 0D jz short loc_1046A
seg000:045D 51 push cx
seg000:045E B9 FF FF mov cx, 0FFFFh
seg000:0461 32 C0 xor al, al
seg000:0463 F2 AE repne scasb
seg000:0465 4F dec di
seg000:0466 B0 5C mov al, 5Ch ; '\'
seg000:0468 AA stosb
seg000:0469 59 pop cx
seg000:046A
seg000:046A loc_1046A: ; CODE XREF: maybe_lib_sub_103FC+44j
seg000:046A ; maybe_lib_sub_103FC+59j ...
seg000:046A 2B CE sub cx, si
seg000:046C F3 A4 rep movsb
seg000:046E 32 C0 xor al, al
seg000:0470 AA stosb
seg000:0471 C5 76 06 lds si, [bp+arg_0]
seg000:0474 46 inc si
seg000:0475 8B FE mov di, si
seg000:0477
seg000:0477 loc_10477: ; CODE XREF: maybe_lib_sub_103FC+8Fj
seg000:0477 AC lodsb
seg000:0478 0A C0 or al, al
seg000:047A 74 11 jz short loc_1048D
seg000:047C 3C 5C cmp al, 5Ch ; '\'
seg000:047E 74 0D jz short loc_1048D
seg000:0480 3C 61 cmp al, 61h ; 'a'
seg000:0482 72 06 jb short loc_1048A
seg000:0484 3C 7A cmp al, 7Ah ; 'z'
seg000:0486 77 02 ja short loc_1048A
seg000:0488 2C 20 sub al, 20h ; ' '
seg000:048A
seg000:048A loc_1048A: ; CODE XREF: maybe_lib_sub_103FC+86j
seg000:048A ; maybe_lib_sub_103FC+8Aj ...
seg000:048A AA stosb
seg000:048B EB EA jmp short loc_10477
seg000:048D ; ---------------------------------------------------------------------------
seg000:048D
seg000:048D loc_1048D: ; CODE XREF: maybe_lib_sub_103FC+7Ej
seg000:048D ; maybe_lib_sub_103FC+82j
seg000:048D 81 7D FE 5C 2E cmp word ptr [di-2], 2E5Ch
seg000:0492 75 04 jnz short loc_10498
seg000:0494 4F dec di
seg000:0495 4F dec di
seg000:0496 EB 1C jmp short loc_104B4
seg000:0498 ; ---------------------------------------------------------------------------
seg000:0498
seg000:0498 loc_10498: ; CODE XREF: maybe_lib_sub_103FC+96j
seg000:0498 81 7D FE 2E 2E cmp word ptr [di-2], 2E2Eh
seg000:049D 75 15 jnz short loc_104B4
seg000:049F 80 7D FD 5C cmp byte ptr [di-3], 5Ch ; '\'
seg000:04A3 75 0F jnz short loc_104B4
seg000:04A5 83 EF 03 sub di, 3
seg000:04A8 80 7D FF 3A cmp byte ptr [di-1], 3Ah ; ':'
seg000:04AC 74 06 jz short loc_104B4
seg000:04AE
seg000:04AE loc_104AE: ; CODE XREF: maybe_lib_sub_103FC+B6j
seg000:04AE 4F dec di
seg000:04AF 80 3D 5C cmp byte ptr [di], 5Ch ; '\'
seg000:04B2 75 FA jnz short loc_104AE
seg000:04B4
seg000:04B4 loc_104B4: ; CODE XREF: maybe_lib_sub_103FC+9Aj
seg000:04B4 ; maybe_lib_sub_103FC+A1j ...
seg000:04B4 0A C0 or al, al
seg000:04B6 75 D2 jnz short loc_1048A
seg000:04B8 80 7D FF 3A cmp byte ptr [di-1], 3Ah ; ':'
seg000:04BC 75 03 jnz short loc_104C1
seg000:04BE B0 5C mov al, 5Ch ; '\'
seg000:04C0 AA stosb
seg000:04C1
seg000:04C1 loc_104C1: ; CODE XREF: maybe_lib_sub_103FC+C0j
seg000:04C1 32 C0 xor al, al
seg000:04C3 AA stosb
seg000:04C4 5F pop di
seg000:04C5 5E pop si
seg000:04C6 1F pop ds
seg000:04C7 5D pop bp
seg000:04C8 CA 04 00 retf 4
seg000:04C8 _maybe_lib_sub_103FC endp
the function seems to be coded original in C due to the bp/sp usage - but could it be that it was coded in assembler and someone implemented the retf wrong?