VOGONS

Common searches


First post, by llm

User metadata
Rank Member
Rank
Member

im currently reverse engineering a small DOS 16bit program and stumbled over invalid prefix combinations comming out of IDA/ndisasm when using MASM to assemble it back to code

TASM and NASM have no problem to assemble these instructions - but MASM/UASM failing
im currious what is the correct code for MASM/UASM to assemble the same? (try to get a binary exact result)

Assembler i tried:

  • TASM - TASM32 5.3 - OK
  • NASM - 2.14.02 (only a file with the two instruction lines) - OK
  • MASM - 14.16.x (from VStudio 2017)- FAIL
  • UASM - v2.49 - FAIL
.model tiny
.code
_start:
;db 0F2h,0A5h
repne movsw
repnz movsw
end _start

Shell-Storm disassembles "F2 A5" to:

repne movsw word ptr es:[di], word ptr [si]

IDA just to:

repne movsw
Last edited by llm on 2019-08-20, 09:25. Edited 1 time in total.

Reply 1 of 11, by Scali

User metadata
Rank l33t
Rank
l33t

I'm not sure if you can actually assemble that code. It's not 'illegal' as such, but it basically doesn't make sense.
movs does not modify any flags, so rep is the only sensible instruction to use with it.
repe/repne would either not run at all, or behave like rep, depending on the value of the zero flag. So it will be error-prone to use this instruction.
I suspect that is why certain assemblers will not allow these prefixes on movs.
There is a simple workaround: just emit the prefix byte manually:

db 0F2h ; repne
movsw

I suppose you could use it to create conditionally executing lods/stos/movs instructions, assuming it works the way you expect it to.
Instead of:

cmp ax, bx
jne skip
rep movsw
skip:

You could do:

cmp ax, bx
repe movsw

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 2 of 11, by llm

User metadata
Rank Member
Rank
Member

MASM got the /Zm option for maximum Masm 5.1 compatiblity (that worked with former MASM version i think) - its shown using /? but it seems not to work - still the error
USAM got the -Zm option but also do not seems to supress the error

thx for the info: i will use a REPNE_MOVS macro in all places to fix that (and other 100% binary identical breaking stuff)

Reply 3 of 11, by jmarsh

User metadata
Rank Oldbie
Rank
Oldbie

Note that repe uses the same prefix as rep (0xF3), so the given example wouldn't work as expected.

Regardless the repe/repne prefixes only check the Z flag when the string instruction updates the flags (only the count register is tested before the first execution) so if the flags are never updated only a zero count register can terminate the loop.

Reply 5 of 11, by jmarsh

User metadata
Rank Oldbie
Rank
Oldbie

Technically replacing F2 A5 with F3 A5 would be correct because the former is undefined, but intel/amd aren't likely to change behaviour of it because it's been mistakenly used in a lot of MBR code.

Reply 6 of 11, by Scali

User metadata
Rank l33t
Rank
l33t
jmarsh wrote:

Note that repe uses the same prefix as rep (0xF3), so the given example wouldn't work as expected.

You're right.
Which also implies that MASM's behaviour is 'syntactic sugar'... Apparently they want to force pairing rep with movs/lods/stos, and repe/repne with cmps/scas.

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 8 of 11, by peterferrie

User metadata
Rank Oldbie
Rank
Oldbie
Scali wrote:

I'm not sure if you can actually assemble that code. It's not 'illegal' as such, but it basically doesn't make sense.
movs does not modify any flags, so rep is the only sensible instruction to use with it.

It depends very much on one thing: if the Z flag was controlled beforehand.

cmp dl, 12h
repne movsw

will perform the copy if DL wasn't 12h. i.e. it's a conditional copy, or a way to update SI and DI without altering flags further.
The same as repz lodsb, for example, to conditionally update SI without altering flags further.

Reply 9 of 11, by jmarsh

User metadata
Rank Oldbie
Rank
Oldbie

That is incorrect. repe/repne do not check the initial value of the Z flag, it is only checked after the string instruction updates it.
For instructions that don't update the flags, repe and repne act identically (both as plain rep).

Reply 11 of 11, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie

imo ne/nz is for usage on scas/cmps than movs.

--/\-[ Stu : Bloody Cactus :: [ https://bloodycactus.com :: http://kråketær.com ]-/\--