Linker Error

Just starting out? Need help? Post your questions and find answers here.
NikitaOdnorob98
User
User
Posts: 74
Joined: Fri Jun 29, 2012 4:50 pm

Linker Error

Post by NikitaOdnorob98 »

Hello everybody! I found this code on Assembler for calculating MD5 hash of file.

Code: Select all

DisableDebugger
EnableASM

; // MD5 context.
!Struc MD5_CTX
!{
!  .state rd 4
!  .buffer rb 128
!  .bitsize rd 2
!  .padLen rd 1
!  .blocks rd 1
!  .readblocks rd 1
!  .pbuf rd 1
!  .remainedbytes rd 1
!  .lastBlocks rd 1
!}
Structure MD5_CTX
  state.l[4]    ; state (ABCD)
  buffer.b[128] ; buffer for MD5Final
  bitsize.q
  padLen.l
  blocks.l
  readblocks.l
  pbuf.l
  remainedbytes.l
  lastBlocks.l
EndStructure

#BufferSize=8192 ;128*64. (BufferSize must be a multiple of 64.)
#BlocksPerBuffer= #BufferSize/64

;{ Constants for MD5Transform routine.
#S11 = 7
#S12 = 12
#S13 = 17
#S14 = 22

#S21 = 5
#S22 = 9
#S23 = 14
#S24 = 20

#S31 = 4
#S32 = 11
#S33 = 16
#S34 = 23

#S41 = 6
#S42 = 10
#S43 = 15
#S44 = 21
;}

Global *ctx.MD5_CTX = ?ctx

Macro FF(a, b, c, d, x, s, ac)
  ;(((c ! d) & b) ! d)
  MOV esi, c
  XOr esi, d
  And esi, b
  XOr esi, d
  
  ADD a, esi
  ADD a, dword [x]
  ADD a, ac
  ROL a, s
  ADD a, b
  ;   a + (F(b, c, d) + x + ac)
  ;   ROTATE_LEFT(a, s)
  ;   a + b
EndMacro

Macro GG(a, b, c, d, x, s, ac)
  ;(((b ! c) & d) ! c)
  MOV esi, b
  XOr esi, c
  And esi, d
  XOr esi, c
  
  ADD a, esi
  ADD a, dword [x]
  ADD a, ac
  ROL a, s
  ADD a, b
  ;   a + (G(b, c, d) + x + ac)
  ;   ROTATE_LEFT(a, s)
  ;   a + b
EndMacro

Macro HH(a, b, c, d, x, s, ac)
  ;(b ! c ! d)
  MOV esi, b
  XOr esi, c
  XOr esi, d
  
  ADD a, esi
  ADD a, dword [x]
  ADD a, ac
  ROL a, s
  ADD a, b
  ;   a + (H(b, c, d) + x + ac)
  ;   ROTATE_LEFT(a, s)
  ;   a + b
EndMacro

Macro II(a, b, c, d, x, s, ac)
  ;(((~d) | b) ! c)
  MOV esi, d
  Not esi
  Or esi, b
  XOr esi, c
  
  ADD a, esi
  ADD a, dword [x]
  ADD a, ac
  ROL a, s
  ADD a, b
  ;   a + (I(b, c, d) + x + ac)
  ;   ROTATE_LEFT(a, s)
  ;   a + b
EndMacro

;MD5 basic transformation. Transforms state based on block.
Procedure MD5Transform()
  !MOV esi, ctx.state
  MOV eax, dword [esi]
  MOV ebx, dword [esi+4]
  MOV ecx, dword [esi+8]
  MOV edx, dword [esi+12]
  
  ;  // Round 1
  FF(eax, ebx, ecx, edx, edi, #S11, $d76aa478); // 1
  FF(edx, eax, ebx, ecx, edi+4, #S12, $e8c7b756); // 2
  FF(ecx, edx, eax, ebx, edi+8, #S13, $242070db); // 3
  FF(ebx, ecx, edx, eax, edi+12, #S14, $c1bdceee); // 4
  FF(eax, ebx, ecx, edx, edi+16, #S11, $f57c0faf); // 5
  FF(edx, eax, ebx, ecx, edi+20, #S12, $4787c62a); // 6
  FF(ecx, edx, eax, ebx, edi+24, #S13, $a8304613); // 7
  FF(ebx, ecx, edx, eax, edi+28, #S14, $fd469501); // 8
  FF(eax, ebx, ecx, edx, edi+32, #S11, $698098d8); // 9
  FF(edx, eax, ebx, ecx, edi+36, #S12, $8b44f7af); // 10
  FF(ecx, edx, eax, ebx, edi+40, #S13, $ffff5bb1); // 11
  FF(ebx, ecx, edx, eax, edi+44, #S14, $895cd7be); // 12
  FF(eax, ebx, ecx, edx, edi+48, #S11, $6b901122); // 13
  FF(edx, eax, ebx, ecx, edi+52, #S12, $fd987193); // 14
  FF(ecx, edx, eax, ebx, edi+56, #S13, $a679438e); // 15
  FF(ebx, ecx, edx, eax, edi+60, #S14, $49b40821); // 16
  
  ;  // Round 2
  GG(eax, ebx, ecx, edx, edi+ 4, #S21, $f61e2562); // 17
  GG(edx, eax, ebx, ecx, edi+24, #S22, $c040b340); // 18
  GG(ecx, edx, eax, ebx, edi+44, #S23, $265e5a51); // 19
  GG(ebx, ecx, edx, eax, edi   , #S24, $e9b6c7aa); // 20
  GG(eax, ebx, ecx, edx, edi+20, #S21, $d62f105d); // 21
  GG(edx, eax, ebx, ecx, edi+40, #S22,  $2441453); // 22
  GG(ecx, edx, eax, ebx, edi+60, #S23, $d8a1e681); // 23
  GG(ebx, ecx, edx, eax, edi+16, #S24, $e7d3fbc8); // 24
  GG(eax, ebx, ecx, edx, edi+36, #S21, $21e1cde6); // 25
  GG(edx, eax, ebx, ecx, edi+56, #S22, $c33707d6); // 26
  GG(ecx, edx, eax, ebx, edi+12, #S23, $f4d50d87); // 27
  GG(ebx, ecx, edx, eax, edi+32, #S24, $455a14ed); // 28
  GG(eax, ebx, ecx, edx, edi+52, #S21, $a9e3e905); // 29
  GG(edx, eax, ebx, ecx, edi+ 8, #S22, $fcefa3f8); // 30
  GG(ecx, edx, eax, ebx, edi+28, #S23, $676f02d9); // 31
  GG(ebx, ecx, edx, eax, edi+48, #S24, $8d2a4c8a); // 32
  
  ;  // Round 3
  HH(eax, ebx, ecx, edx, edi+20, #S31, $fffa3942); // 33
  HH(edx, eax, ebx, ecx, edi+32, #S32, $8771f681); // 34
  HH(ecx, edx, eax, ebx, edi+44, #S33, $6d9d6122); // 35
  HH(ebx, ecx, edx, eax, edi+56, #S34, $fde5380c); // 36
  HH(eax, ebx, ecx, edx, edi+4, #S31, $a4beea44); // 37
  HH(edx, eax, ebx, ecx, edi+16, #S32, $4bdecfa9); // 38
  HH(ecx, edx, eax, ebx, edi+28, #S33, $f6bb4b60); // 39
  HH(ebx, ecx, edx, eax, edi+40, #S34, $bebfbc70); // 40
  HH(eax, ebx, ecx, edx, edi+52, #S31, $289b7ec6); // 41
  HH(edx, eax, ebx, ecx, edi, #S32, $eaa127fa); // 42
  HH(ecx, edx, eax, ebx, edi+12, #S33, $d4ef3085); // 43
  HH(ebx, ecx, edx, eax, edi+24, #S34,  $4881d05); // 44
  HH(eax, ebx, ecx, edx, edi+36, #S31, $d9d4d039); // 45
  HH(edx, eax, ebx, ecx, edi+48, #S32, $e6db99e5); // 46
  HH(ecx, edx, eax, ebx, edi+60, #S33, $1fa27cf8); // 47
  HH(ebx, ecx, edx, eax, edi+8, #S34, $c4ac5665); // 48
  
  ;  // Round 4
  II(eax, ebx, ecx, edx, edi, #S41, $f4292244); // 49
  II(edx, eax, ebx, ecx, edi+28, #S42, $432aff97); // 50
  II(ecx, edx, eax, ebx, edi+56, #S43, $ab9423a7); // 51
  II(ebx, ecx, edx, eax, edi+20, #S44, $fc93a039); // 52
  II(eax, ebx, ecx, edx, edi+48, #S41, $655b59c3); // 53
  II(edx, eax, ebx, ecx, edi+12, #S42, $8f0ccc92); // 54
  II(ecx, edx, eax, ebx, edi+40, #S43, $ffeff47d); // 55
  II(ebx, ecx, edx, eax, edi+4, #S44, $85845dd1); // 56
  II(eax, ebx, ecx, edx, edi+32, #S41, $6fa87e4f); // 57
  II(edx, eax, ebx, ecx, edi+60, #S42, $fe2ce6e0); // 58
  II(ecx, edx, eax, ebx, edi+24, #S43, $a3014314); // 59
  II(ebx, ecx, edx, eax, edi+52, #S44, $4e0811a1); // 60
  II(eax, ebx, ecx, edx, edi+16, #S41, $f7537e82); // 61
  II(edx, eax, ebx, ecx, edi+44, #S42, $bd3af235); // 62
  II(ecx, edx, eax, ebx, edi+8, #S43, $2ad7d2bb); // 63
  II(ebx, ecx, edx, eax, edi+36, #S44, $eb86d391); // 64
  
  !MOV esi, ctx.state
  ADD dword [esi], eax
  ADD dword [esi+4], ebx
  ADD dword [esi+8], ecx
  ADD dword [esi+12], edx
  
EndProcedure

Procedure MD5Init(*ctx.MD5_CTX, totalsize.q, *buf)
  ;Load magic initialization constants.
  *ctx\state[0] = $67452301
  *ctx\state[1] = $efcdab89
  *ctx\state[2] = $98badcfe
  *ctx\state[3] = $10325476
  
  *ctx\bitsize = totalsize << 3
  totalsize+8
  
  *ctx\padLen = 63-(totalsize & %111111)
  *ctx\blocks = ((totalsize + *ctx\padLen + 1) >> 6)
  
  *ctx\readblocks = 0
  *ctx\pbuf = *buf
  totalsize-8
  
  If *ctx\padLen>55
    *ctx\lastBlocks=2
  Else
    *ctx\lastBlocks=1
  EndIf
  *ctx\remainedbytes = totalsize - ((*ctx\blocks-*ctx\lastBlocks) << 6)
  *ctx\blocks - *ctx\lastBlocks
EndProcedure

Procedure MD5Update()
  !MOV edi, dword [ctx.pbuf]
  XOr ecx, ecx
  !@@:
  PUSH ecx
  ;PUSH edi
  MD5Transform()
  ;POP edi
  
  ADD edi, 64
  !INC dword [ctx.readblocks]
  
  POP ecx
  INC ecx
  CMP ecx, #BlocksPerBuffer
  !jl @b
EndProcedure

Procedure MD5Final()
  CLD
  !MOV edi, dword [ctx.pbuf]
  XOr ecx, ecx
  !@@:
  !MOV ebx, dword [ctx.readblocks]
  !CMP ebx, dword [ctx.blocks]
  !JGE .n
  
  PUSH ecx
  ;PUSH edi
  MD5Transform()
  ;POP edi
  
  ADD edi, 64
  !INC dword [ctx.readblocks]
  
  POP ecx
  INC ecx
  
  CMP ecx, #BlocksPerBuffer
  !jle @b
  ProcedureReturn
  
  !.n:
  MOV esi, edi
  !MOV edi, ctx.buffer
  !MOV ecx, dword [ctx.remainedbytes]
  !REP MOVSB
  
  ;pad bytes
  MOV byte [edi], $80
  INC edi
  XOr eax, eax
  MOV ecx, dword [ctx.padLen]
  !REP STOSB
  
  ;copy size
  !MOV eax, dword [ctx.bitsize]
  !MOV ebx, dword [ctx.bitsize+4]
  MOV dword [edi], eax
  MOV dword [edi+4], ebx
  
  !mov eax, dword [ctx.lastBlocks]
  MOV edi, ctx.buffer
  !.lp:
  PUSH eax
  ;PUSH edi
  MD5Transform()
  ;POP edi
  
  ADD edi, 64
  POP eax
  DEC eax
  CMP eax, 0
  !JNE .lp
EndProcedure

Procedure.s MD5str()
  !MOV esi, ctx.state
  MOV eax, [esi]
  MOV ebx, [esi+4]
  MOV ecx, [esi+8]
  MOV edx, [esi+12]
  BSWAP eax
  BSWAP ebx
  BSWAP ecx
  BSWAP edx
  MOV [esi], edx
  MOV [esi+4], ecx
  MOV [esi+8], ebx
  MOV [esi+12], eax
  tmp$= RSet(Hex(PeekQ(@*ctx\state[2])), 16, "0")+RSet(Hex(PeekQ(@*ctx\state[0])), 16, "0")
  ProcedureReturn tmp$
EndProcedure

Procedure.s FastMD5(FileName$)
  Protected hFile, *buf, fs.q, rs.q, len, tmp$
  hFile=ReadFile(#PB_Any, FileName$)
  If hFile
    *buf=AllocateMemory(#BufferSize)
    fs=Lof(hFile)
    
    MD5Init(*ctx, fs, *buf)
    rs=0
    
    Repeat
      len=ReadData(hFile, *buf, #BufferSize)
      rs+len
      
      If (len < #BufferSize) Or (rs = fs)
        MD5Final()
        Break
      Else
        MD5Update()
      EndIf
    ForEver
    
    tmp$=MD5str()

    CloseFile(hFile)
  EndIf
  
  FreeMemory(*buf)
  
  ProcedureReturn LCase(tmp$)
EndProcedure

DataSection
  ctx:
  !ctx MD5_CTX
EndDataSection
When I run program with debugger, all's OK. But if debugger isn't enable (or I want create EXE), I get error:
POLINK: fatal error: Invalid or corrupt object 'Purebasic.obj'
How fix that?
Last edited by NikitaOdnorob98 on Sun Feb 15, 2015 4:27 pm, edited 1 time in total.
infratec
Always Here
Always Here
Posts: 7664
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Linker Error

Post by infratec »

Your code is not working.
The datasection with ctx is missing. (cause of ?ctx)

Bernd
NikitaOdnorob98
User
User
Posts: 74
Joined: Fri Jun 29, 2012 4:50 pm

Re: Linker Error

Post by NikitaOdnorob98 »

@infratec Sorry, I forgot about DataSection

Code: Select all

DataSection
  ctx:
  !ctx MD5_CTX
EndDataSection
NikitaOdnorob98
User
User
Posts: 74
Joined: Fri Jun 29, 2012 4:50 pm

Re: Linker Error

Post by NikitaOdnorob98 »

Please! Somebody, help me. Why I get a linker error when debugger is disabled?
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Linker Error

Post by bbanelli »

Because you actually can't compile code you have as an EXE. Since your code only contains functions without any operational code.

If you add as much as Delay(1) somewhere outside your functions, it will compile as EXE. But to what end exactly, that's only for you to know. :)

BTW, truth is, error thrown by PB is somewhat confusing...
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
NikitaOdnorob98
User
User
Posts: 74
Joined: Fri Jun 29, 2012 4:50 pm

Re: Linker Error

Post by NikitaOdnorob98 »

Unfortunately, this did not help :( This code doesn't work :cry: :cry:
POLINK: fatal error: Invalid or corrupt object 'Purebasic.obj'

Code: Select all

DisableDebugger
EnableASM

; // MD5 context.
!Struc MD5_CTX
!{
!  .state rd 4
!  .buffer rb 128
!  .bitsize rd 2
!  .padLen rd 1
!  .blocks rd 1
!  .readblocks rd 1
!  .pbuf rd 1
!  .remainedbytes rd 1
!  .lastBlocks rd 1
!}
Structure MD5_CTX
  state.l[4]    ; state (ABCD)
  buffer.b[128] ; buffer for MD5Final
  bitsize.q
  padLen.l
  blocks.l
  readblocks.l
  pbuf.l
  remainedbytes.l
  lastBlocks.l
EndStructure

#BufferSize=65536 ;128*64. (BufferSize must be a multiple of 64.)
#BlocksPerBuffer= #BufferSize/64

;{ Constants for MD5Transform routine.
#S11 = 7
#S12 = 12
#S13 = 17
#S14 = 22

#S21 = 5
#S22 = 9
#S23 = 14
#S24 = 20

#S31 = 4
#S32 = 11
#S33 = 16
#S34 = 23

#S41 = 6
#S42 = 10
#S43 = 15
#S44 = 21
;}

Global *ctx.MD5_CTX = ?ctx

Macro FF(a, b, c, d, x, s, ac)
  ;(((c ! d) & b) ! d)
  MOV esi, c
  XOr esi, d
  And esi, b
  XOr esi, d
  
  ADD a, esi
  ADD a, dword [x]
  ADD a, ac
  ROL a, s
  ADD a, b
  ;   a + (F(b, c, d) + x + ac)
  ;   ROTATE_LEFT(a, s)
  ;   a + b
EndMacro

Macro GG(a, b, c, d, x, s, ac)
  ;(((b ! c) & d) ! c)
  MOV esi, b
  XOr esi, c
  And esi, d
  XOr esi, c
  
  ADD a, esi
  ADD a, dword [x]
  ADD a, ac
  ROL a, s
  ADD a, b
  ;   a + (G(b, c, d) + x + ac)
  ;   ROTATE_LEFT(a, s)
  ;   a + b
EndMacro

Macro HH(a, b, c, d, x, s, ac)
  ;(b ! c ! d)
  MOV esi, b
  XOr esi, c
  XOr esi, d
  
  ADD a, esi
  ADD a, dword [x]
  ADD a, ac
  ROL a, s
  ADD a, b
  ;   a + (H(b, c, d) + x + ac)
  ;   ROTATE_LEFT(a, s)
  ;   a + b
EndMacro

Macro II(a, b, c, d, x, s, ac)
  ;(((~d) | b) ! c)
  MOV esi, d
  Not esi
  Or esi, b
  XOr esi, c
  
  ADD a, esi
  ADD a, dword [x]
  ADD a, ac
  ROL a, s
  ADD a, b
  ;   a + (I(b, c, d) + x + ac)
  ;   ROTATE_LEFT(a, s)
  ;   a + b
EndMacro

;MD5 basic transformation. Transforms state based on block.
Procedure MD5Transform()
  !MOV esi, ctx.state
  MOV eax, dword [esi]
  MOV ebx, dword [esi+4]
  MOV ecx, dword [esi+8]
  MOV edx, dword [esi+12]
  
  ;  // Round 1
  FF(eax, ebx, ecx, edx, edi, #S11, $d76aa478); // 1
  FF(edx, eax, ebx, ecx, edi+4, #S12, $e8c7b756); // 2
  FF(ecx, edx, eax, ebx, edi+8, #S13, $242070db); // 3
  FF(ebx, ecx, edx, eax, edi+12, #S14, $c1bdceee); // 4
  FF(eax, ebx, ecx, edx, edi+16, #S11, $f57c0faf); // 5
  FF(edx, eax, ebx, ecx, edi+20, #S12, $4787c62a); // 6
  FF(ecx, edx, eax, ebx, edi+24, #S13, $a8304613); // 7
  FF(ebx, ecx, edx, eax, edi+28, #S14, $fd469501); // 8
  FF(eax, ebx, ecx, edx, edi+32, #S11, $698098d8); // 9
  FF(edx, eax, ebx, ecx, edi+36, #S12, $8b44f7af); // 10
  FF(ecx, edx, eax, ebx, edi+40, #S13, $ffff5bb1); // 11
  FF(ebx, ecx, edx, eax, edi+44, #S14, $895cd7be); // 12
  FF(eax, ebx, ecx, edx, edi+48, #S11, $6b901122); // 13
  FF(edx, eax, ebx, ecx, edi+52, #S12, $fd987193); // 14
  FF(ecx, edx, eax, ebx, edi+56, #S13, $a679438e); // 15
  FF(ebx, ecx, edx, eax, edi+60, #S14, $49b40821); // 16
  
  ;  // Round 2
  GG(eax, ebx, ecx, edx, edi+ 4, #S21, $f61e2562); // 17
  GG(edx, eax, ebx, ecx, edi+24, #S22, $c040b340); // 18
  GG(ecx, edx, eax, ebx, edi+44, #S23, $265e5a51); // 19
  GG(ebx, ecx, edx, eax, edi   , #S24, $e9b6c7aa); // 20
  GG(eax, ebx, ecx, edx, edi+20, #S21, $d62f105d); // 21
  GG(edx, eax, ebx, ecx, edi+40, #S22,  $2441453); // 22
  GG(ecx, edx, eax, ebx, edi+60, #S23, $d8a1e681); // 23
  GG(ebx, ecx, edx, eax, edi+16, #S24, $e7d3fbc8); // 24
  GG(eax, ebx, ecx, edx, edi+36, #S21, $21e1cde6); // 25
  GG(edx, eax, ebx, ecx, edi+56, #S22, $c33707d6); // 26
  GG(ecx, edx, eax, ebx, edi+12, #S23, $f4d50d87); // 27
  GG(ebx, ecx, edx, eax, edi+32, #S24, $455a14ed); // 28
  GG(eax, ebx, ecx, edx, edi+52, #S21, $a9e3e905); // 29
  GG(edx, eax, ebx, ecx, edi+ 8, #S22, $fcefa3f8); // 30
  GG(ecx, edx, eax, ebx, edi+28, #S23, $676f02d9); // 31
  GG(ebx, ecx, edx, eax, edi+48, #S24, $8d2a4c8a); // 32
  
  ;  // Round 3
  HH(eax, ebx, ecx, edx, edi+20, #S31, $fffa3942); // 33
  HH(edx, eax, ebx, ecx, edi+32, #S32, $8771f681); // 34
  HH(ecx, edx, eax, ebx, edi+44, #S33, $6d9d6122); // 35
  HH(ebx, ecx, edx, eax, edi+56, #S34, $fde5380c); // 36
  HH(eax, ebx, ecx, edx, edi+4, #S31, $a4beea44); // 37
  HH(edx, eax, ebx, ecx, edi+16, #S32, $4bdecfa9); // 38
  HH(ecx, edx, eax, ebx, edi+28, #S33, $f6bb4b60); // 39
  HH(ebx, ecx, edx, eax, edi+40, #S34, $bebfbc70); // 40
  HH(eax, ebx, ecx, edx, edi+52, #S31, $289b7ec6); // 41
  HH(edx, eax, ebx, ecx, edi, #S32, $eaa127fa); // 42
  HH(ecx, edx, eax, ebx, edi+12, #S33, $d4ef3085); // 43
  HH(ebx, ecx, edx, eax, edi+24, #S34,  $4881d05); // 44
  HH(eax, ebx, ecx, edx, edi+36, #S31, $d9d4d039); // 45
  HH(edx, eax, ebx, ecx, edi+48, #S32, $e6db99e5); // 46
  HH(ecx, edx, eax, ebx, edi+60, #S33, $1fa27cf8); // 47
  HH(ebx, ecx, edx, eax, edi+8, #S34, $c4ac5665); // 48
  
  ;  // Round 4
  II(eax, ebx, ecx, edx, edi, #S41, $f4292244); // 49
  II(edx, eax, ebx, ecx, edi+28, #S42, $432aff97); // 50
  II(ecx, edx, eax, ebx, edi+56, #S43, $ab9423a7); // 51
  II(ebx, ecx, edx, eax, edi+20, #S44, $fc93a039); // 52
  II(eax, ebx, ecx, edx, edi+48, #S41, $655b59c3); // 53
  II(edx, eax, ebx, ecx, edi+12, #S42, $8f0ccc92); // 54
  II(ecx, edx, eax, ebx, edi+40, #S43, $ffeff47d); // 55
  II(ebx, ecx, edx, eax, edi+4, #S44, $85845dd1); // 56
  II(eax, ebx, ecx, edx, edi+32, #S41, $6fa87e4f); // 57
  II(edx, eax, ebx, ecx, edi+60, #S42, $fe2ce6e0); // 58
  II(ecx, edx, eax, ebx, edi+24, #S43, $a3014314); // 59
  II(ebx, ecx, edx, eax, edi+52, #S44, $4e0811a1); // 60
  II(eax, ebx, ecx, edx, edi+16, #S41, $f7537e82); // 61
  II(edx, eax, ebx, ecx, edi+44, #S42, $bd3af235); // 62
  II(ecx, edx, eax, ebx, edi+8, #S43, $2ad7d2bb); // 63
  II(ebx, ecx, edx, eax, edi+36, #S44, $eb86d391); // 64
  
  !MOV esi, ctx.state
  ADD dword [esi], eax
  ADD dword [esi+4], ebx
  ADD dword [esi+8], ecx
  ADD dword [esi+12], edx
  
EndProcedure

Procedure MD5Init(*ctx.MD5_CTX, totalsize.q, *buf)
  ;Load magic initialization constants.
  *ctx\state[0] = $67452301
  *ctx\state[1] = $efcdab89
  *ctx\state[2] = $98badcfe
  *ctx\state[3] = $10325476
  
  *ctx\bitsize = totalsize << 3
  totalsize+8
  
  *ctx\padLen = 63-(totalsize & %111111)
  *ctx\blocks = ((totalsize + *ctx\padLen + 1) >> 6)
  
  *ctx\readblocks = 0
  *ctx\pbuf = *buf
  totalsize-8
  
  If *ctx\padLen>55
    *ctx\lastBlocks=2
  Else
    *ctx\lastBlocks=1
  EndIf
  *ctx\remainedbytes = totalsize - ((*ctx\blocks-*ctx\lastBlocks) << 6)
  *ctx\blocks - *ctx\lastBlocks
EndProcedure

Procedure MD5Update()
  !MOV edi, dword [ctx.pbuf]
  XOr ecx, ecx
  !@@:
  PUSH ecx
  ;PUSH edi
  MD5Transform()
  ;POP edi
  
  ADD edi, 64
  !INC dword [ctx.readblocks]
  
  POP ecx
  INC ecx
  CMP ecx, #BlocksPerBuffer
  !jl @b
EndProcedure

Procedure MD5Final()
  CLD
  !MOV edi, dword [ctx.pbuf]
  XOr ecx, ecx
  !@@:
  !MOV ebx, dword [ctx.readblocks]
  !CMP ebx, dword [ctx.blocks]
  !JGE .n
  
  PUSH ecx
  ;PUSH edi
  MD5Transform()
  ;POP edi
  
  ADD edi, 64
  !INC dword [ctx.readblocks]
  
  POP ecx
  INC ecx
  
  CMP ecx, #BlocksPerBuffer
  !jle @b
  ProcedureReturn
  
  !.n:
  MOV esi, edi
  !MOV edi, ctx.buffer
  !MOV ecx, dword [ctx.remainedbytes]
  !REP MOVSB
  
  ;pad bytes
  MOV byte [edi], $80
  INC edi
  XOr eax, eax
  MOV ecx, dword [ctx.padLen]
  !REP STOSB
  
  ;copy size
  !MOV eax, dword [ctx.bitsize]
  !MOV ebx, dword [ctx.bitsize+4]
  MOV dword [edi], eax
  MOV dword [edi+4], ebx
  
  !mov eax, dword [ctx.lastBlocks]
  MOV edi, ctx.buffer
  !.lp:
  PUSH eax
  ;PUSH edi
  MD5Transform()
  ;POP edi
  
  ADD edi, 64
  POP eax
  DEC eax
  CMP eax, 0
  !JNE .lp
EndProcedure

Procedure.s MD5str()
  !MOV esi, ctx.state
  MOV eax, [esi]
  MOV ebx, [esi+4]
  MOV ecx, [esi+8]
  MOV edx, [esi+12]
  BSWAP eax
  BSWAP ebx
  BSWAP ecx
  BSWAP edx
  MOV [esi], edx
  MOV [esi+4], ecx
  MOV [esi+8], ebx
  MOV [esi+12], eax
  tmp$= RSet(Hex(PeekQ(@*ctx\state[2])), 16, "0")+RSet(Hex(PeekQ(@*ctx\state[0])), 16, "0")
  ProcedureReturn tmp$
EndProcedure

Procedure.s FastMD5(FileName$)
  Protected hFile, *buf, fs.q, rs.q, len, tmp$
  hFile=ReadFile(#PB_Any, FileName$)
  If hFile
    *buf=AllocateMemory(#BufferSize)
    fs=Lof(hFile)
    
    MD5Init(*ctx, fs, *buf)
    rs=0
    
    Repeat
      len=ReadData(hFile, *buf, #BufferSize)
      rs+len
      
      If (len < #BufferSize) Or (rs = fs)
        MD5Final()
        Break
      Else
        MD5Update()
      EndIf
    ForEver
    
    tmp$=MD5str()

    CloseFile(hFile)
  EndIf
  
  FreeMemory(*buf)
  
  ProcedureReturn LCase(tmp$)
EndProcedure

t1 = ElapsedMilliseconds()
md5$ = FastMD5("C:\2012.mkv")
t2 = ElapsedMilliseconds()

MessageRequester("", Str(t2-t1))
MessageRequester("", md5$)


DataSection
  ctx:
  !ctx MD5_CTX
EndDataSection
Dude
Addict
Addict
Posts: 1907
Joined: Mon Feb 16, 2015 2:49 pm

Re: Linker Error

Post by Dude »

NikitaOdnorob98 wrote:I found this code on Assembler for calculating MD5 hash of file.
Forget your problem and use this: http://www.purebasic.com/documentation/ ... print.html
NikitaOdnorob98
User
User
Posts: 74
Joined: Fri Jun 29, 2012 4:50 pm

Re: Linker Error

Post by NikitaOdnorob98 »

Dude
The standard function is slow. I specifically was looking for the code in assembler, because speed is important to me
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Linker Error

Post by luis »

bbanelli wrote:Because you actually can't compile code you have as an EXE. Since your code only contains functions without any operational code.
UH ? This is not true, you can create an exe with a source completely empty, or with just procedures. It will still contain a lot of PB stuff initializing and shutting down the empty program environment.

It has nothing to do with the problem anyway.
bbanelli wrote: If you add as much as Delay(1) somewhere outside your functions, it will compile as EXE
UH ? What ? I've tried anyway... didn't make a difference.


@NikitaOdnorob98

Try changing the datasection this way:

Code: Select all

DataSection
  Data.i 0  ; just add this little tiny line
  ctx:
  !ctx MD5_CTX
EndDataSection
BTW: FreeMemory(*buf) inside FastMD5() it's in the wrong place, should be inside the IF.
NikitaOdnorob98 wrote:Please! Somebody, help me. Why I get a linker error when debugger is disabled?
BTW 2: Did you wait exactly a month on purpose biting your lips in restrain before asking for help again or it was just a coincidence ?
"Have you tried turning it off and on again ?"
User avatar
bbanelli
Enthusiast
Enthusiast
Posts: 544
Joined: Tue May 28, 2013 10:51 pm
Location: Europe
Contact:

Re: Linker Error

Post by bbanelli »

luis wrote:
bbanelli wrote: If you add as much as Delay(1) somewhere outside your functions, it will compile as EXE
UH ? What ? I've tried anyway... didn't make a difference.
Well, I'd swear it worked that way, I tried it again and no good.

It compiles to executable file on Linux without a problem, though.
"If you lie to the compiler, it will get its revenge."
Henry Spencer
https://www.pci-z.com/
NikitaOdnorob98
User
User
Posts: 74
Joined: Fri Jun 29, 2012 4:50 pm

Re: Linker Error

Post by NikitaOdnorob98 »

luis, thank you very much!! Code works!!! I get a 4 seconds speed up on file 5.38 GB (74s vs 78s)
Did you wait exactly a month on purpose biting your lips in restrain before asking for help again or it was just a coincidence ?
No, it's coincidence :)

P.S. Is it bug or not?
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Linker Error

Post by luis »

NikitaOdnorob98 wrote:No, it's coincidence :)
OK :)
NikitaOdnorob98 wrote: P.S. Is it bug or not?
I would say no.
You are using an empty DataSection/EndDataSection pair without any Data statement inside.
What you are putting there is through inline ASM, so that's unsupported territory.

In the specific case, I noticed when you use DataSection/EndDataSection with Data, PB generates code like this:

Code: Select all

section '.data' data readable writeable
PB_DataSectionStart:
  dd     1,2,3
SYS_EndDataSection:
but in your case the code generated was:

Code: Select all

section '.data' data readable writeable
l_ctx:
ctx MD5_CTX
SYS_EndDataSection:
It seems PB outputs the PB_DataSectionStart: (and other code as well referencing it) only when encounters at least a Data statement.

To force it, I added a dummy "Data.i 0" before the inline ASM stuff and the PB label (they must stay near each other).

I don't know where you found the code, maybe it was working in an older PB version which was behaving differently.
"Have you tried turning it off and on again ?"
Post Reply