Hi,
I get an error in both versions 32-64 ...
mywindow1.asm(22) : Error A2028: Instruction prefix not allowed
mywindow1.asm: 38 lines, 1 passes, 2 ms, 0 warnings, 1 errors
Microsoft (R) Incremental Linker Version 14.16.27024.1
Copyright (C) Microsoft Corporation. All rights reserved.
with this source code
option casemap:none
.const
Green equ 7
Red equ 5
.DATA
hInstance7 qword 0
CommandLine7 qword 0
hInstance qword 0
CommandLine qword 0
hInstance6 qword 0
CommandLine6 qword 0
G_TlsMap DWORD 8 DUP (?)
.code
mainCRTStartup proc
lock bt G_TlsMap,esi
mov ecx,Green
mov hInstance, rax
mov CommandLine7, rax
mov hInstance7, Red
mov CommandLine6, rax
mov hInstance6, Red
mov CommandLine, rax
mov ecx, eax
ret
align 4
mainCRTStartup endp
end
At the same time macro assembler successfully accepts this command
Assembling: mywindow1.asm
Microsoft (R) Incremental Linker Version 14.16.27024.1
Copyright (C) Microsoft Corporation. All rights reserved.
Press any key to continue . . .
Older versions of macro assembler also accept this instruction :icon_redface:
BT — Bit Test
Opcode Instruction Op/En 64-bit Mode Compat/Leg Mode Description
0F A3 /r BT r/m16, r16 MR Valid Valid Store selected bit in CF flag.
0F A3 /r BT r/m32, r32 MR Valid Valid Store selected bit in CF flag.
REX.W + 0F A3 /r BT r/m64, r64 MR Valid N.E. Store selected bit in CF flag.
0F BA /4 ib BT r/m16, imm8 MI Valid Valid Store selected bit in CF flag.
0F BA /4 ib BT r/m32, imm8 MI Valid Valid Store selected bit in CF flag.
REX.W + 0F BA /4 ib BT r/m64, imm8 MI Valid N.E. Store selected bit in CF flag.
Protected Mode Exceptions ¶
#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If the DS, ES, FS, or GS register contains a NULL segment selector.
#SS(0) If a memory operand effective address is outside the SS segment limit.
#PF(fault-code) If a page fault occurs.
#AC(0) If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.
#UD If the LOCK prefix is used.
Real-Address Mode Exceptions ¶
#GP If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS If a memory operand effective address is outside the SS segment limit.
#UD If the LOCK prefix is used.
Virtual-8086 Mode Exceptions ¶
#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0) If a memory operand effective address is outside the SS segment limit.
#PF(fault-code) If a page fault occurs.
#AC(0) If alignment checking is enabled and an unaligned memory reference is made.
#UD If the LOCK prefix is used.
Compatibility Mode Exceptions ¶
Same exceptions as in protected mode.
64-Bit Mode Exceptions ¶
#SS(0) If a memory address referencing the SS segment is in a non-canonical form.
#GP(0) If the memory address is in a non-canonical form.
#PF(fault-code) If a page fault occurs.
#AC(0) If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.
#UD If the LOCK prefix is used.
The analysis is correct, but what do you need it for? The code assembles with MASM, with UAsm, you can use this:
db 0F0h
bt G_TlsMap, esi
And then you run it, and it crashes 8)
Quote from: jj2007 on December 02, 2018, 06:51:21 AM
The analysis is correct, but what do you need it for? The code assembles with MASM, with UAsm, you can use this:
db 0F0h
bt G_TlsMap, esi
And then you run it, and it crashes 8)
:biggrin: to throw an exception #UD, it would be possible to use hardcode, I wonder why, some instructions are blocked, but others are not. For example according to intel ..
CLAC—Clear AC Flag in EFLAGS Register
Protected Mode Exceptions
#UD If the LOCK prefix is used.
If the CPL > 0.
If CPUID.(EAX=07H, ECX=0H):EBX.SMAP[bit 20] = 0.
Real-Address Mode Exceptions
#UD If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.SMAP[bit 20] = 0.
Virtual-8086 Mode Exceptions
#UD The CLAC instruction is not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
#UD If the LOCK prefix is used.
If the CPL > 0.
If CPUID.(EAX=07H, ECX=0H):EBX.SMAP[bit 20] = 0.
64-Bit Mode Exceptions
#UD If the LOCK prefix is used.
If the CPL > 0.
If CPUID.(EAX=07H, ECX=0H):EBX.SMAP[bit 20] = 0
The same can be said about the call command
lock clac
lock callbut in this case the macro assembler says exactly the same -
Assembling: mywindow1.asm
mywindow1.asm(26) : error A2068:instruction prefix not allowed
Microsoft (R) Incremental Linker Version 14.16.27024.1
Copyright (C) Microsoft Corporation. All rights reserved.
LINK : fatal error LNK1181: cannot open input file 'mywindow1.obj'
Press any key to continue . . .
I cant see the logic in this example :icon_confused:, intel says you can use it, macro assembler says differently, UASM says, you can not use. The question is, who is right ?! :icon_rolleyes:
Assembles with MASM version 14.00.23026.0 (which you should never ever use for work because it has very serious bugs):
int 3
nops 2
clac
nops 2
lock bt G_TlsMap, esi
nops 4
This is what Olly sees (both instructions throw exceptions):
0040637B ³. CC int3
0040637C ³? 90 nop
0040637D ³? 90 nop
0040637E ³? 0F01CA clac
00406381 ³? 90 nop
00406382 ³? 90 nop
00406383 ³? F0:0FA335 F881400 lock bt [4081F8], esi ; LOCK prefix is not allowed
0040638B ³? 90 nop
0040638C ³. 90 nop
0040638D ³? 90 nop
We are talking about a MASM bug which must be reported (https://developercommunity.visualstudio.com/content/problem/79839/vs-2017-bugs-and-suggestions.html) to Microsoft Corporation (sometimes they fix them, most times not ::)).
According to Intel:
The LOCK prefix can be prepended only to the following instructions and only to those forms of the instructions
where the destination operand is a memory operand: ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B,
CMPXCHG16B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG. If the LOCK prefix is used with one of
these instructions and the source operand is a memory operand, an undefined opcode exception (#UD) may be
generated.
There is no LOCK BT.
Hi AW,
Quote from: AW on December 02, 2018, 06:08:31 PM
There is no LOCK BT.
:icon_exclaim:
Quote from: jj2007 on December 02, 2018, 08:24:00 AM
00406383 ³? F0:0FA335 F881400 lock bt [4081F8], esi ; LOCK prefix is not allowed
Quote from: AW on December 02, 2018, 06:08:31 PM
According to Intel:
The LOCK prefix can be prepended only to the following instructions and only to those forms of the instructions
where the destination operand is a memory operand: ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B,
CMPXCHG16B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG. If the LOCK prefix is used with one of
these instructions and the source operand is a memory operand, an undefined opcode exception (#UD) may be
generated.
That's right, I thought about it, the conclusion that the architecture does not forbid me to use ud exceptions and each assembler developer independently decides how to handle such instructions.
(https://i.ibb.co/ngYQmk7/lock.png)