# array of 2 integers (each size 4 bytes)
|
|
# load address of flag into fx register
|
|
# access flag[] with 0(%fx,%index,4)
|
|
# where %index is a register holding 0 or 1
|
|
# index reg contains 0 -> flag[0], if 1->flag[1]
|
|
.var flag 2
|
|
|
|
# global turn variable
|
|
.var turn
|
|
|
|
# global count
|
|
.var count
|
|
|
|
.main
|
|
|
|
# put address of flag into fx
|
|
lea flag, %fx
|
|
|
|
# assume thread ID is in bx (0 or 1, scale by 4 to get proper flag address)
|
|
mov %bx, %cx # bx: self, now copies to cx
|
|
neg %cx # cx: - self
|
|
add $1, %cx # cx: 1 - self
|
|
|
|
.acquire
|
|
mov $1, 0(%fx,%bx,4) # flag[self] = 1
|
|
mov %cx, turn # turn = 1 - self
|
|
|
|
.spin1
|
|
mov 0(%fx,%cx,4), %ax # flag[1-self]
|
|
test $1, %ax
|
|
jne .fini # if flag[1-self] != 1, skip past loop to .fini
|
|
|
|
.spin2 # just labeled for fun, not needed
|
|
mov turn, %ax
|
|
test %cx, %ax # compare 'turn' and '1 - self'
|
|
je .spin1 # if turn==1-self, go back and start spin again
|
|
|
|
# fall out of spin
|
|
.fini
|
|
|
|
# do critical section now
|
|
mov count, %ax
|
|
add $1, %ax
|
|
mov %ax, count
|
|
|
|
.release
|
|
mov $0, 0(%fx,%bx,4) # flag[self] = 0
|
|
|
|
|
|
# end case: make sure it's other's turn
|
|
mov %cx, turn # turn = 1 - self
|
|
halt
|
|
|