fork download
  1. global _start
  2.  
  3. section .text
  4.  
  5. ;
  6. ; [ebp+8] is pointer to string
  7. ; [ebp+12] is pointer to pattern
  8. ; returns eax==0 for false, eax==1 for true
  9. ;
  10. match:
  11. push ebp
  12. mov ebp, esp
  13. sub esp, 4 ; local I (index) is [ebp-4]
  14. push esi ; we use esi, edi and eax,
  15. push edi ; but eax is changed anyway
  16. mov esi, [ebp+8] ; esi always points to the string
  17. mov edi, [ebp+12] ; edi -------------------- pattern
  18. .again:
  19. cmp byte [edi], 0 ; pattern end?
  20. jne .not_end
  21. cmp byte [esi], 0 ; string end?
  22. jne near .false ; out of range
  23. jmp .true
  24. .not_end:
  25. cmp byte [edi], '*'
  26. jne .not_star
  27. ; now the "star cycle" begins
  28. mov dword [ebp-4], 0 ; I := 0
  29. .star_loop:
  30. ; prepare the recursive call
  31. mov eax, edi ; second arg of match is pattern+1
  32. inc eax
  33. push eax
  34. mov eax, esi ; first arg of match is string+I
  35. add eax, [ebp-4] ; prepare the recursive call
  36. push eax
  37. call match
  38. add esp, 8 ; remove params from stack
  39. test eax, eax ; what is returned, true or false?
  40. jnz .true ; if 1, then match is found, return 1
  41. add eax, [ebp-4]
  42. cmp byte [esi+eax], 0 ; may be string ended?
  43. je .false ; if so, no more possibilities to try
  44. inc dword [ebp-4] ; I := I + 1
  45. jmp .star_loop ; try the next possibility
  46. .not_star:
  47. mov al, [edi] ; we already know pattern isn't ended
  48. cmp al, '?'
  49. je .quest
  50. cmp al, [esi] ; if the string's over, this cmp fails
  51. jne .false ; as well as if the chars differ
  52. jmp .goon
  53. .quest:
  54. cmp byte [esi], 0 ; we only need to check for string end
  55. jz .false
  56. .goon:
  57. inc esi
  58. inc edi
  59. jmp .again
  60. .true:
  61. mov eax, 1
  62. jmp .quit
  63. .false:
  64. xor eax, eax
  65. .quit:
  66. pop edi
  67. pop esi
  68. mov esp, ebp
  69. pop ebp
  70. ret
  71.  
  72.  
  73.  
  74. ;
  75. ; MAIN PROGRAM
  76. ;
  77. _start:
  78. pop eax
  79. cmp eax, 3
  80. jne wrong_args
  81. pop esi ; ignore argv[0]
  82. pop esi ; get argv[1]
  83. pop edi ; get argv[2]
  84. mov [string], esi
  85. mov [pattern], edi
  86.  
  87. push edi
  88. push esi
  89. call match
  90. add esp, 8
  91. test eax, eax
  92. jz print_no
  93.  
  94. mov edx, 4 ; print yes
  95. mov ecx, m_yes
  96. mov ebx, 1
  97. mov eax, 4
  98. int 80h
  99. jmp quit
  100. print_no: ; print no
  101. mov edx, 4
  102. mov ecx, m_no
  103. mov ebx, 1
  104. mov eax, 4
  105. int 80h
  106. jmp quit
  107.  
  108. wrong_args: ; say wrong args
  109. mov edx, m_wrong_len
  110. mov ecx, m_wrong
  111. mov ebx, 1
  112. mov eax, 4
  113. int 80h
  114. jmp quit
  115.  
  116.  
  117. quit:
  118. mov ebx, 0
  119. mov eax, 1
  120. int 80h
  121.  
  122. section .bss
  123.  
  124. string resd 1
  125. pattern resd 1
  126.  
  127. section .data
  128.  
  129. m_yes db "YES", 10
  130. m_no db "NO ", 10
  131. m_wrong db "wrong arguments count, must be 2", 10
  132. m_wrong_len equ $-m_wrong
  133.  
Success #stdin #stdout 0.01s 5280KB
stdin
Standard input is empty
stdout
wrong arguments count, must be 2