Assembly instruction prefix: LOCK

Programming, for all ages and all languages.
Post Reply
Cjreek
Member
Member
Posts: 70
Joined: Thu May 28, 2009 2:41 pm
Location: Germany

Assembly instruction prefix: LOCK

Post by Cjreek »

Hi,

Just a little question:

As far as I understand LOCK it essentially does "nothing" on a single core CPU.
Is this right?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Assembly instruction prefix: LOCK

Post by Combuster »

Even with a single CPU core, there can be several other devices trying to access memory.

LOCK initially blocked the entire system bus. Now it only does that for uncached memory, but it still tries to enforce full read-modify-write atomicity against all non-CPU devices that way.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Cjreek
Member
Member
Posts: 70
Joined: Thu May 28, 2009 2:41 pm
Location: Germany

Re: Assembly instruction prefix: LOCK

Post by Cjreek »

Okay thanks.

I saw someone in this forum who made an (x86-) emulator and I'm trying to do it myself because that sounds really interesting.

So my new question is: every operation in my current code is atomic at the moment. Is it okay to just ignore LOCK or do I really have to emulate how the processor may take several ticks for some instructions and how this can lead to other devices interfering with the current write operation of the cpu (if the cpu didn't lock the bus)?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Assembly instruction prefix: LOCK

Post by Brendan »

Hi,
Cjreek wrote:So my new question is: every operation in my current code is atomic at the moment. Is it okay to just ignore LOCK or do I really have to emulate how the processor may take several ticks for some instructions and how this can lead to other devices interfering with the current write operation of the cpu (if the cpu didn't lock the bus)?
If there is never more than 1 "thing" accessing (emulated) memory at a time, then you can ignore LOCK. This includes emulators that emulate multi-CPU; if the emulator executes one instruction from one CPU, then executes the next instruction from the next CPU, etc. It doesn't include (e.g.) a multi-threaded emulator that use one thread to emulate a single CPU plus another thread to emulate DMA/bus mastering devices.

Note: You would also need to emulate the "invalid LOCK prefix" case correctly. For example, if someone does "lock add eax,ebx" then you're supposed to invoke the invalid opcode exception and can't just execute it as if it was "add eax, ebx".


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Cjreek
Member
Member
Posts: 70
Joined: Thu May 28, 2009 2:41 pm
Location: Germany

Re: Assembly instruction prefix: LOCK

Post by Cjreek »

Okay that's nice. This saves me a lot of work :)

Throwing some invalid opcode exceptions is fine and not a big deal.

But wait:
LOCK add cl, dl
This compiles into
F0 00 D1
which represents
ADD r/m8, r8
http://ref.x86asm.net/coder32.html

Is this a valid opcode altough the destination operand is a register and no memory location?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Assembly instruction prefix: LOCK

Post by Combuster »

r/m
That's a shorthand of register/memory

The D1 is actually 11 010 001 binary. There are 8 registers, which means you need three bits to define one. That leaves you two extra bits you will want to use instead of letting them go to waste. 00 is a simple memory operand, 01 and 10 are memory operands with offsets, and 11 means a register instead.

(and please don't use colours, they make reading a pain)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Assembly instruction prefix: LOCK

Post by Brendan »

Hi,
Cjreek wrote:Is this a valid opcode altough the destination operand is a register and no memory location?
No.

For the bytes "0xF0, 0x00, 0x??" the third byte is a ModRM byte that determines if the instruction has a memory location or not. If the ModRM byte says there's a memory location then the instruction is valid. If the ModRM byte says there's no memory location then the instruction is illegal.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Cjreek
Member
Member
Posts: 70
Joined: Thu May 28, 2009 2:41 pm
Location: Germany

Re: Assembly instruction prefix: LOCK

Post by Cjreek »

Combuster wrote:
r/m
That's a shorthand of register/memory

The D1 is actually 11 010 001 binary. There are 8 registers, which means you need three bits to define one. That leaves you two extra bits you will want to use instead of letting them go to waste. 00 is a simple memory operand, 01 and 10 are memory operands with offsets, and 11 means a register instead.

(and please don't use colours, they make reading a pain)
Yes I know those things (otherwise I couldn't have done anything with my emulator :mrgreen: )
It's just that the destination operand of this opcode 0x00 can either be a register (11) or a memory location (00-10).

And I thought LOCK is only valid if the destination operand is actually a memory location.

@Brendan:

Okay that's what I wanted to know :)

It just found it to be strange that NASM did compile this without an error altough this opcode will always end in an invalid opcode exception :-k

EDIT:

WAIT again! I just compiled this with nasm and loaded it with qemu:

Code: Select all

[BITS 16]
mov ax, 0xAABB
LOCK add cl, dl
mov ax, 0xCCDD
jmp $

times 510-($-$$) db 0
db 0x55
db 0xAA
after booting my image I printed eax and it's 0xCCDD. So LOCK add cl, dl seems to be valid!
Octocontrabass
Member
Member
Posts: 5513
Joined: Mon Mar 25, 2013 7:01 pm

Re: Assembly instruction prefix: LOCK

Post by Octocontrabass »

Cjreek wrote:So LOCK add cl, dl seems to be valid!
Currently, qemu does not catch invalid locks (other than "lock nop"). On a more accurate emulator or a real CPU, your test will fail.
Cjreek
Member
Member
Posts: 70
Joined: Thu May 28, 2009 2:41 pm
Location: Germany

Re: Assembly instruction prefix: LOCK

Post by Cjreek »

Okay than my emulator may be more accurate than qemu :mrgreen:
And I think there's no more confusion about LOCK so thanks to everyone who helped me with this issue :)
Czernobyl
Member
Member
Posts: 47
Joined: Sun Dec 26, 2010 1:04 pm

Re: Assembly instruction prefix: LOCK

Post by Czernobyl »

Fwiw, and for the record, use of the LOCK prefix was unrestricted on x86 prior to 80386, so : " lock add cl,dl " is valid on these early intel processors. Also for the record, it appears the opcode position 0xF1
on these processors was an undocumented alias for LOCK (0xF0).
Post Reply