1

I have the following code with a simple assembly procedure

.686p
.model flat, stdcall 
.mmx
.xmm


.code 
DataString DB 'AGIJKSZ', 0FFH ;

MyProc1 proc 

    vpbroadcastd ymm0, [4 bytes of JJJJ]
    vpcmpeqb ymm0, ymm0, [DataString] 
    vpmovmskb eax, ymm0 
    tzcnt eax, eax       
    ret        
MyProc1 endp 

end

However, when I try to compile it, I get Missing operator in expression on vpbroadcastd and

Error MSB3721 The command "ml.exe /c /nologo /Zi /Fo"Debug\JAAsm.obj" /W3 /errorReport:prompt /TaJAAsm.asm" exited with code 1.'

Is it becouse I chose wrong CPU or didn't include the instruction set, or there is something in my VS2015 project setup? Or maybe there is something missing in the code?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Jarek N
  • 55
  • 9

1 Answers1

5

[4 bytes of JJJJ] is not valid syntax, it appears someone was suggesting that you want to create a memory operand that points to 4 bytes each containing the letter J. I think the intention was to suggest doing something like:

.686p
.model flat, stdcall 
.mmx
.xmm

.data
DataString DB 'AGIJKSZ', 0FFH
JMask DB 'JJJJ'

.code 
MyProc1 proc
    vpbroadcastd ymm0, dword ptr [JMask]
    vpcmpeqb ymm0, ymm0, [DataString] 
    vpmovmskb eax, ymm0 
    tzcnt eax, eax       
    ret        
MyProc1 endp 

end

I created a 4 byte string called JMask and then use that as a memory operand for the vpbroadcastd instruction. Alternatively you could use this equivalent code:

.686p
.model flat, stdcall 
.mmx
.xmm

.data
DataString DB 'AGIJKSZ', 0FFH
JMask DD 'JJJJ'

.code 
MyProc1 proc
    vpbroadcastd ymm0, [JMask]
    vpcmpeqb ymm0, ymm0, [DataString] 
    vpmovmskb eax, ymm0 
    tzcnt eax, eax       
    ret        
MyProc1 endp 

end

This version creates Jmask as a DWORD that contains the 4 bytes JJJJ. The advantage to this is that it is unnecessary to override the memory operand with dword ptr like the first version of the program. The generated instructions for both versions will be identical.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • 1
    @JarekN : If that solved the problem you can consider accepting the answer. This marks it as solved. More on how and why you can accept an answer can be found here: https://meta.stackexchange.com/a/5235/271768 . I also updated the answer with an alternative way to express the array (using `dd`). – Michael Petch Mar 13 '18 at 22:20
  • 1
    I realized that this came about from a comment by @petercordes in the comments under this thread: https://stackoverflow.com/questions/49232650/most-effective-code-to-search-character-in-string – Michael Petch Mar 13 '18 at 22:24
  • @JarekN: Suggestion, put the `db 'JJJJ'` first, so it's 4-byte aligned regardless of string length. Or use `mov eax, 'J'` / `movd xmm0, eax` / `vpbroadcastb ymm0, xmm0`. I used a broadcast from memory in that comment because it's a single instruction that runs as a single load uop (no ALU uops), but normally you'd have the search character in a register. (And you could use `vpbroadcastb` to broadcast a byte instead of a dword: same speed with a register source, but slower from memory because CPUs have hardware support for dword/qword broadcasts built in to the load ports.) – Peter Cordes Mar 14 '18 at 06:06
  • I tried to use ml.exe from masm32 to generate a listing, but I get syntax error on `vpbroadcastd` , `vpcmpeqb` and `eax` – Jarek N Mar 14 '18 at 14:55
  • That is because MASM32 is using a version of ML that is very old and at the time didn't have AVX instruction support (AVX wasn't available). You will have to get a modern version of ML (You can get it in the free download of Visual Studio 2017. You can dispense with MASM32 and use the VS idea for assembly development if you wish. – Michael Petch Mar 14 '18 at 14:57