1

MASM code:

.model flat, stdcall
option prologue:none
option epilogue:none
.code
lockc proc value : dword
mov ecx, [esp+04h]
_loop:
lock bts [ecx], 0
pause
jc _loop
ret
lockc endp
end

C code:

typedef struct { DWORD l; }lck_t;
extern DWORD __stdcall lockc(lck_t* l);

ignore any typos that may have happened, i copied by hand. the code compiles fine but i keep getting the ESP error thing.

i call the function from 2 threads and it always shows me the error after the first execution, but i cannot see why that would be.

Carol Victor
  • 331
  • 1
  • 7
  • This is a slow way to take a lock. Your `pause` runs even in the uncontended success "fast" path, and is mostly unnecessary because you're spinning on `lock bts` instead of a pure load. (That's a bad thing; you don't want every waiting thread to be competing for exclusive ownership of the cache line while the thread that has it locked is trying to do a store that unlocks it. See [Locks around memory manipulation via inline assembly](https://stackoverflow.com/a/37246263)) – Peter Cordes Mar 30 '21 at 00:07

1 Answers1

2

This function uses the stdcall calling convention and takes an argument, but does not free the space the argument occupies, so the stack will be imbalanced after it returns (the caller won't adjust the stack to get rid of the arguments, because for calling an stcall function that is not necessary).

Change ret to ret 4.

harold
  • 61,398
  • 6
  • 86
  • 164