fhtw.asm 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. %include "os_dependent_stuff.asm"
  2. %macro hash_function 5
  3. ; clobbers rcx and all arguments
  4. ; %1 = key pointer
  5. ; %2 = key length
  6. ; %3 = desired return register
  7. ; %4 & 5 are scratch
  8. xor %3, %3
  9. %%begin:
  10. cmp %2, 8
  11. jl %%last_bits
  12. crc32 %3, qword[%1]
  13. add %1, 8
  14. sub %2, 8
  15. jnz %%begin
  16. jmp %%ret
  17. %%last_bits:
  18. ; zero out the higher bits of the last partial byte
  19. ; r11 holds the last byte
  20. mov %4, [%1]
  21. ; shift operator can only use cl, so put the number of bits remaining into rcx
  22. mov rcx, %2
  23. shl rcx, 3 ; multiply by 8 to get bits
  24. ; rdx will hold the desired mask
  25. mov %5, 1
  26. shl %5, cl
  27. dec %5
  28. and %4, %5
  29. crc32 %3, %4
  30. %%ret:
  31. %endmacro
  32. global fhtw_new
  33. fhtw_new:
  34. push rdi ; store requested size for later
  35. ; rdi is the size of the the table
  36. ; we need 3 pieces of metadata - occupancy, capacity, size of info word in bits
  37. ; and 3 arrays - keys, values, and hop info words
  38. ; info word size does not change the amount of memory allocated; just says how many bits we use
  39. inc rdi
  40. mov rax, 24
  41. mul rdi
  42. ; load arguments to mmap
  43. mov rsi, rax ; size
  44. mov r10, MAP_SHARED | MAP_ANON ; not backed by a file
  45. mov r8, -1 ; file descripter is -1
  46. mov r9, 0 ; no offset
  47. mov rax, SYSCALL_MMAP
  48. mov rdx, PROT_READ | PROT_WRITE ; read/write access
  49. mov rdi, 0 ; we don't care about the particular address
  50. syscall
  51. test rax, rax
  52. ;js .error ; local error label
  53. ; initialize metadata
  54. ; occupancy at [rax] has already been set to 0 by mmap
  55. pop r11
  56. mov [rax + 8], r11 ; store capacity
  57. dec r11
  58. bsr r11, r11
  59. mov [rax + 16], r11 ; store size of info word - logarithmic in capacity
  60. ret
  61. global fhtw_free
  62. fhtw_free:
  63. ; put size of memory to be freed in rsi
  64. mov r11, [rdi + 8]
  65. inc r11
  66. mov rax, 24
  67. mul r11
  68. ; arguments to munmap
  69. ; rdi already set to address
  70. mov rsi, rax
  71. mov rax, SYSCALL_MUNMAP
  72. syscall
  73. ret
  74. global fhtw_set
  75. fhtw_set:
  76. ; rdi = table pointer
  77. ; rsi = key pointer
  78. ; rdx = key length
  79. ; rcx = value
  80. ; r8 = value length? -- used in function!
  81. ; make sure there is room in the table
  82. mov r11, [rdi]
  83. cmp r11, [rdi + 8]
  84. je .table_full
  85. ; calculate hash
  86. mov r8, rsi ; save key pointer in r8
  87. mov r9, rcx ; save value in r9
  88. hash_function rsi, rdx, rax, r11, r10
  89. ; linear probe for empty space
  90. div [rdi + 8] ; hash value is in rax, we divide by table size.
  91. shl rdx, 3 ; get index in bits
  92. add rdx, rdi
  93. add rdx, 24 ; add rdi + 24 to get start of key array
  94. .begin:
  95. cmp qword[rdx], 0
  96. je .end
  97. add rdx, 8
  98. jmp .begin
  99. .end:
  100. ; empty space is in rdx
  101. ; if empty space is within length of bitmap, insert
  102. ; STUB just insert into empty space - linear probe table
  103. mov [rdx], r8 ; insert key
  104. mov rax, [rdi + 8] ; next 3 lines calculate value position
  105. shl rax, 3
  106. add rax, rdx
  107. mov [rax], r9 ; insert value
  108. ; if space is too far away, hop the space back until it is close enough
  109. ; when it's close enough, jump to insert
  110. ; increase occupancy
  111. ret
  112. .table_full:
  113. ; return error code
  114. mov rax, -1
  115. ret
  116. global fhtw_get
  117. fhtw_get:
  118. ; table in rdi
  119. ; key in rsi
  120. ; keylen in rdx
  121. ; STUB linear probing
  122. mov r8, rsi
  123. mov r9, rdx
  124. hash_function rsi, rdx, rax, r10, r11
  125. mov r10, rdi
  126. div [r10 + 8] ; hash value is in rax, we divide by table size.
  127. ; get pointer in the key array into rdx
  128. shl rdx, 3 ; get index in bits
  129. add rdx, r10
  130. add rdx, 24 ; add rdi + 24 to get start of key array
  131. .begin:
  132. ; if we've hit an empty space the key is not valid
  133. cmp [rdx], 0
  134. jz .fail
  135. ; TODO loop back if we're at the end of the table
  136. ; TODO return fail if we've reached our original position
  137. ; repe cmps compares strings one byte at a time; it expects
  138. ; rcx == strlen, rdi == str1, rsi == str2
  139. ; clobbers all registers, so we have to reset them each time
  140. mov rcx, r9
  141. mov rdi, r8
  142. mov rsi, [rdx]
  143. repe cmps
  144. ; zero flag will be set if the two strings are equal
  145. jz .success
  146. add rdx, 8
  147. jmp .begin
  148. .success:
  149. .fail:
  150. global fhtw_hash
  151. fhtw_hash:
  152. hash_function rdi, rsi, rax, rdx, r11
  153. ret