• Create Account

## some assembly unknowns

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

14 replies to this topic

### #1/ fir   Members

Posted 08 July 2014 - 12:05 PM

i wanted to generate some raw binary but for modern sse assembly

i took such function

ZeroMemorySSE:
mov edx, dword [esp+4]
mov ecx, dword [esp+8]
xorps xmm0, xmm0
loop11:
movdqu oword [edx], xmm0
sub    ecx, 16
jg     loop11
ret


### #2Dave Hunt  Members

Posted 08 July 2014 - 12:10 PM

POPULAR

Is there an actual question in there or is this just YAFR (Yet Another Fir Ramble)?

### #3/ fir   Members

Posted 08 July 2014 - 12:18 PM

those bug eated a 30 minutes of writing

in short - when assembly this to win32 coff and disassembly i got such code

extern loop11                                           ; byte
extern ZeroMemorySSE                                    ; byte

.absolut equ 00000000H                                  ; 0
@feat.00 equ 00000001H                                  ; 1

SECTION .text   align=16 execute                        ; section number 1, code

.text:  ; Local function
mov     edx, dword [esp+4H]                     ; 0000 _ 8B. 54 24, 04
mov     ecx, dword [esp+8H]                     ; 0004 _ 8B. 4C 24, 08
xorps   xmm0, xmm0                              ; 0008 _ 0F 57. C0
?_001:  movdqu  oword [edx], xmm0                       ; 000B _ F3: 0F 7F. 02
add     edx, 16                                 ; 000F _ 83. C2, 10
sub     ecx, 16                                 ; 0012 _ 83. E9, 10
jg      ?_001                                   ; 0015 _ 7F, F4
ret                                             ; 0017 _ C3

do not use code tag as do not want to risk a text damaging

when assembly it to raw bin i got many 66/67 prefixes added (seen on picture)

I got a question if this version with prefixes will work too such as the above (when linked to 32 bit app or those prefixes made it wrong? (in short)

when disassembly it shows as old 16 bit code - but i wonder if i can make it working or not and i must generate it in raw binary again with some setting

### #4L. Spiro  Members

Posted 08 July 2014 - 01:01 PM

66 and 67 are superfluous 16-bit 8086 prefixes that you should remove when compiling for 32-bit machines.
If these are not executed in x86’s VM86 virtual mode they will be misinterpreted by the CPU and crash or cause undesirable results.

L. Spiro

Edited by L. Spiro, 08 July 2014 - 01:01 PM.

### #5Nypyren  Members

Posted 08 July 2014 - 01:36 PM

The 66 prefix is used in some SIMD encodings.  MOVDQA and XORPD use it though, not MOVDQU or XORPS.

It is also used with other general purpose instructions to override the operand size (on 32-bit and 64-bit mode, it switches to 16-bit operand size, and in 16-bit mode it switches to 32-bit operand size)

67, on the other hand, when used in a 64-bit process, allows you to select 32-bit address size in certain situations which may be useful.

Encoding 8B:  MOV Gv, Ev;  both Gv and Ev respect the operandSize override.  Since you're using a memory form of Ev, it also respects addressSize override.  In this case you must remove the prefixes since it will cause the encoding 66 67 8B 54 24 to become "mov dx, word [Si+0x24]" instead, causing another catastrophic problem:  your 04 will no longer be part of the instruction, and will be decoded as its own instruction.  At that point your program will likely catastrophically fail since you've "derailed" the instruction pointer.

They are not obsolete, but if you use them wrong, it will cause undesirable results like Spiro said.

Edited by Nypyren, 08 July 2014 - 01:59 PM.

### #6L. Spiro  Members

Posted 08 July 2014 - 01:40 PM

These 66 and 67’s are prefixes to the first 2 mov commands (and some of the following standard non-SIMD commands) for 16-bit architectures.

L. Spiro

Edited by L. Spiro, 08 July 2014 - 01:40 PM.

### #7/ fir   Members

Posted 08 July 2014 - 02:19 PM

The 66 prefix is used in some SIMD encodings.  MOVDQA and XORPD use it though, not MOVDQU or XORPS.

It is also used with other general purpose instructions to override the operand size (on 32-bit and 64-bit mode, it switches to 16-bit operand size, and in 16-bit mode it switches to 32-bit operand size)

67, on the other hand, when used in a 64-bit process, allows you to select 32-bit address size in certain situations which may be useful.

Encoding 8B:  MOV Gv, Ev;  both Gv and Ev respect the operandSize override.  Since you're using a memory form of Ev, it also respects addressSize override.  In this case you must remove the prefixes since it will cause the encoding 66 67 8B 54 24 to become "mov dx, word [Si+0x24]" instead, causing another catastrophic problem:  your 04 will no longer be part of the instruction, and will be decoded as its own instruction.  At that point your program will likely catastrophically fail since you've "derailed" the instruction pointer.

They are not obsolete, but if you use them wrong, it will cause undesirable results like Spiro said.

alright, could you answer me if the code generated in raw bin (seen as this jpeg picture) is 16 bit code or what? or is this 32 bit code to run in 16 bit mode? why nasm generated it such way? it would be strange if it would generate code that purpose is tu crash anywhere.. and if not crashing would it be able to really run sse code in 16bit mode or something ? (sorry if the questions is a bit indepth, but maybe someone will know this)

ps when disasembly it was bring

c:\asm>ndisasm -b32 -o40001000h -a tezt.bin

40001000  66678B5424        mov dx,[si+0x24]
40001007  678B4C24          mov ecx,[si+0x24]
4000100B  080F              or [edi],cl
4000100D  57                push edi
4000100E  C067F30F          shl byte [edi-0xd],byte 0xf
40001012  7F02              jg 0x40001016
40001018  6683E910          sub cx,byte +0x10
4000101C  7FF1              jg 0x4000100f
4000101E  C3                ret

extremally wrong maybe i should try -b16

here

c:\asm>ndisasm -b16 -o40001000h -a tezt.bin

40001000  66678B542404      mov edx,[dword esp+0x4]
40001006  66678B4C2408      mov ecx,[dword esp+0x8]
4000100C  0F57C0            xorps xmm0,xmm0
4000100F  67F30F7F02        movdqu [edx],xmm0
40001018  6683E910          sub ecx,byte +0x10
4000101C  7FF1              jg 0x100f
4000101E  C3                ret

seem okay but do such hex is able to run on 32 windows?

some flag i think must be setted somewhere to treat this as

some 32-16 mode (as i suspect this is 32 bit code but with some

16 bit args by default)

probably this explains most of the think - i need to find some flag

to denay this 16 bit default

Edited by fir, 08 July 2014 - 02:39 PM.

### #8/ fir   Members

Posted 08 July 2014 - 02:28 PM

66 and 67 are superfluous 16-bit 8086 prefixes that you should remove when compiling for 32-bit machines.
If these are not executed in x86’s VM86 virtual mode they will be misinterpreted by the CPU and crash or cause undesirable results.

L. Spiro

if so i guess this code is unusable at all - is this code for 16 bit dos or something? - if so probably such dos code would crash on xmm cammands..

- i need to generate raw bin but proper 32 bit code

### #9beans222  Members

Posted 08 July 2014 - 02:29 PM

If you use NASM to output a raw binary it will assume 16-bit code for a DOS .com executable.

http://www.nasm.us/doc/nasmdoc6.html

New C/C++ Build Tool 'Stir' (doesn't just generate Makefiles, it does the build): https://github.com/space222/stir

### #10/ fir   Members

Posted 08 July 2014 - 02:45 PM

If you use NASM to output a raw binary it will assume 16-bit code for a DOS .com executable.

http://www.nasm.us/doc/nasmdoc6.html

one thing is unclear, what is 16-bit mode , if this is 16 bit why it is using sse modern commands -it seem to be more like 32 with some tendency to 16 bit - or is this really 16 bit...  :/

if someone could explain a bit tnx

tnx for answers, thing is more clear now

Edited by fir, 08 July 2014 - 02:46 PM.

Posted 08 July 2014 - 02:59 PM

Prefix codes 66 and 67 are available even in 32 and 64 bit modes. They are called operand size prefix and address size prefix. The CPU determines the default operand and address sizes from the D bit in the segment descriptors. With these prefixes this can be overriden for single instructions.
AFAIK this is extended for segments with 32 Bit and 64 bit as well. For some SIMD instructions this prefix is mandantory. If you want to know more about that read the programming manuals.

### #12/ fir   Members

Posted 08 July 2014 - 03:15 PM

Prefix codes 66 and 67 are available even in 32 and 64 bit modes. They are called operand size prefix and address size prefix. The CPU determines the default operand and address sizes from the D bit in the segment descriptors. With these prefixes this can be overriden for single instructions.
AFAIK this is extended for segments with 32 Bit and 64 bit as well. For some SIMD instructions this prefix is mandantory. If you want to know more about that read the programming manuals.

alright tnx for info this was ok,

as to D bit in segment descriptor -

does maybe someone know if i could mix such say 16 32 and 64 segments in one app ? what is setting this - windows loader based on some program image, or what.. ?

Posted 08 July 2014 - 03:28 PM

In modern os the segment registers are only set once by the os. They use a flat memory model. Access to the segment descriptors is only possible by the os. Changing the segment registers to some value other than they are set after startup, shall lead to crash/exception.

### #14/ fir   Members

Posted 08 July 2014 - 04:43 PM

In modern os the segment registers are only set once by the os. They use a flat memory model. Access to the segment descriptors is only possible by the os. Changing the segment registers to some value other than they are set after startup, shall lead to crash/exception.

alright

### #15Nypyren  Members

Posted 08 July 2014 - 06:58 PM

alright, could you answer me if the code generated in raw bin (seen as this jpeg picture) is 16 bit code or what? or is this 32 bit code to run in 16 bit mode? why nasm generated it such way? it would be strange if it would generate code that purpose is tu crash anywhere.. and if not crashing would it be able to really run sse code in 16bit mode or something ? (sorry if the questions is a bit indepth, but maybe someone will know this)

ps when disasembly it was bring

c:\asm>ndisasm -b32 -o40001000h -a tezt.bin

40001000  66678B5424        mov dx,[si+0x24]
40001007  678B4C24          mov ecx,[si+0x24]
4000100B  080F              or [edi],cl
4000100D  57                push edi
4000100E  C067F30F          shl byte [edi-0xd],byte 0xf
40001012  7F02              jg 0x40001016
40001018  6683E910          sub cx,byte +0x10
4000101C  7FF1              jg 0x4000100f
4000101E  C3                ret

extremally wrong maybe i should try -b16

here

c:\asm>ndisasm -b16 -o40001000h -a tezt.bin

40001000  66678B542404      mov edx,[dword esp+0x4]
40001006  66678B4C2408      mov ecx,[dword esp+0x8]
4000100C  0F57C0            xorps xmm0,xmm0
4000100F  67F30F7F02        movdqu [edx],xmm0
40001018  6683E910          sub ecx,byte +0x10
4000101C  7FF1              jg 0x100f
4000101E  C3                ret

seem okay but do such hex is able to run on 32 windows?
some flag i think must be setted somewhere to treat this as
some 32-16 mode (as i suspect this is 32 bit code but with some
16 bit args by default)

probably this explains most of the think - i need to find some flag
to denay this 16 bit default

Exactly - the behavior depends on BOTH the CPU's mode for the process (16-bit, 32-bit, or 64-bit are the ones that x86-64 processors support currently) AND the prefix of the instruction. Your encodings were built to be executed in 16-bit mode (this is why the 32-bit operands got assembled with 66 and 67 prefixes). Microsoft PE files (EXEs and DLLs) have field(s) in the headers which specifies which processor and mode the code should be executed in.

Current Windows programs should always target either 32-bit or 64-bit modes, since 16-bit executables are no longer supported on 64-bit editions of Windows.

Edited by Nypyren, 08 July 2014 - 06:59 PM.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.