News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How many registers do I have?

Started by frktons, July 15, 2010, 04:44:02 PM

Previous topic - Next topic

frktons

Hello everybody. I've been a little busy recentely with
C learning, so my MASM/32 experimentations are waiting
for available time.

But I want to do some experimentations nevertheless, and
because I've already done some ADD,MOV, dereferencing
and so on, I'm wondering what else can I do with them, what
kind of instructions can I try, and what registers are available
on my machine, other than the 8 general 32 bit registers and
sons, so to speak, FLAG register, Stack registers and usual 32 bit ones.

According to the Intel Processor Identification Utility, my pc
has got a Core 2 Duo CPU E6600 2.40 Ghz, and is
in the X64 class Processor and can use SSE3 instructions.

I'm asking myself, and somebody who knows better than me,
some basic information about the quantity and type of registers
are there in that machine, what are they used for,
if I can move data from EAX for example to an MMX register
and things like these.

I think all these info are available on INTEL manuals, but before
diving into them and get lost, I'd like some general explanation
if you can help me or give me a link to these info.

One wonderful thing would be a 3 lines complete example of
the general ideas:



««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« *

    .686                                    ; create 32 bit code [?]
    .model flat, stdcall                    ; 32 bit memory model
    option casemap :none                    ; case sensitive

    include \masm32\include\windows.inc     ; always first
    include \masm32\macros\macros.asm       ; MASM support macros

  ; -----------------------------------------------------------------
  ; include files that have MASM format prototypes for function calls
  ; -----------------------------------------------------------------
    include \masm32\include\masm32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc

  ; ------------------------------------------------
  ; Library files that have definitions for function
  ; exports and tested reliable prebuilt code.
  ; ------------------------------------------------
    includelib \masm32\lib\masm32.lib
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

start:                          ; The CODE entry point to the program

    some code here to add or move a register X64 to another
    and print the result, or the use of MMX, EMMX and the like
    exit


; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start                       ; Tell MASM where the program ends



I mean something I can assemble with the masm32 package, I'm using
ML  from vs2010 so it can assemble the last available code I think.

Thanks for your patience.

Frank
Mind is like a parachute. You know what to do in order to use it :-)

BogdanOntanu

While you run on an 32 bits OS and /or compile targeting an 32bits executable you will not be able to access the additional 64bits general purpose registers. Basically when the CPU is in 32 bits mode or executes an 32 bits executable THEN x64 register are off limits even if your CPU is x64 capable.

To put it blantly in 32 bits you do not have acces to RAX, RCX, RDX,... and R8, R9, to R15 neither to XMM8 ... XMM15. You can only use EAX, ECX, EDX, EBX, ESP,EBP,ESI,EDI and XMM1 to XMM7 even if your CPU is x64 capable. Access to FPU and MMX registers is kind of the same in x32 and in x64

Assumming that you run an 64bits OS like Windows 7 x64 then you could use x64 general purpoose registers but only if you compile for an PE32+ (in fact PE64) executable format target.

The MASM compiler provided in MASM32 package can not do this. You will have to use the 64 bits version of ML. Again unfortunately the x64 bits version of ML does not yet support invoke and many of the more advanced features of the ML 32 bits compiler like .IF .ELESIF .WHILE etc

Hence you can try JWASM, or GoASM or humbly my own assembler: SOL_ASM.

JWASM is the most compatible with MASM/MASM32.
GoASM is kind of different.... to much for my taste but some people here swear by it and it is part of those forums. 
Sol_ASM is somewhere in the middle (you have invoke like in MASM but other things like the include/structures/db/PROC format is more like in TASM)

Then on other sites you can also find FASM or NASM or YASM with even more syntax diferences when compared to MASM.

I suggest that you gain confidence in 32 bits world with MASM32 and move to x64 only later because the transition is not exactly an easy ride but also not very complicated once you know 32bits well enough. Anyway you might get confused unless you have a solid 32bits conceptual base to fallback to.

IMHO JWASM is your best option now if you want to try x64 with a MASM32 like syntax.  Or as a  biased oppinion my own Sol_Asm :D

As for using and moving data to/from from GPR registers to FPU/MMX/SSE3/XMM registers some restrictions do apply but you will just have to learn them... your question is too vague to be answered briefly and clearely.
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

frktons

Quote from: BogdanOntanu on July 15, 2010, 05:27:48 PM
While you run on an 32 bits OS and /or compile targeting an 32bits executable you will not be able to access the additional 64bits general purpose registers.

Basically when the CPU is in 32 bits mode or executes an 32 bits executable x64 is off limits even if your CPU is x64 capable.

Assumming that you run an 64bits OS like Windows 7 x64 then you could use x64 general purpoose registers but only if you compile for an PE32+ (in fact PE64) exectable target.

The MASM compiler provided in MASM32 package can not do this. You will have to use the 64 bits version of ML. Again unfortunately the x64 bits version of ML does not yet support invoke and many of the more advanced features of the ML 32 bits compiler.

Hence you can try JWASM, or GoASM or humbly my own assembler: SOL_ASM.

JWASM is the most compatible with MASM/MASM32.
GoASM is kind of different.... to much for my taste but some people here swear by it and it is part of those forums. 
Sol_ASM is somewhere in the middle (you have invoke like in MASM but other things like the include/structures/db/PROC format is more like in TASM)

Then on other sites you can also find FASM or NASM or YASM with even more syntax diferences when compared to MASM.

I suggest that you gain confidence in 32 bits world with MASM32 and move to x64 only later because the transition is not exactly an easy ride but also not very complicated once you know 32bits well enough. Anyway you might get confused unless you have a solid 32bits conceptual base to fallback to.

IMHO JWASM shold be your best choiche if you want to try x64 with a MASM32 like syntax. Or as a  biased oppinion my own Sol_Asm :D

As for using and moving data to/from from GPR registers to FPU/MMX/SSE3/XMM registers some restrictions do apply but you will just have to learn them... your question is too vague to be answered briefly and clearely.


Thanks, BogdanOntanu.

My machine is X64 and my OS is WIN7/64 bit, but I'm not trying
to shift to 64 bit Assembly for the time being. I'm just a beginner
so I'm going to stay on 32 bit MASM for a while.

According to Wikipedia:
Quote
MMX defined eight registers, known as MM0 through MM7 (henceforth referred to as MMn). To avoid compatibility problems with the context switch mechanisms in existing operating systems, these registers were aliases for the existing x87  FPU stack registers (so no new registers needed to be saved or restored). Hence, anything that was done to the floating point stack would also affect the MMX registers and vice versa. However, unlike the FP stack, the MMn registers are directly addressable (random access).

Each of the MMn registers holds 64 bits (the mantissa-part of a full 80-bit FPU register). The main usage of the MMX instruction set is based on the concept of packed data types, which means that instead of using the whole register for a single 64-bit integer, two 32-bit integers, four 16-bit integers, or eight 8-bit integers may be processed concurrently.

The mapping of the MMX registers onto the existing FPU registers made it somewhat difficult to work with floating point and SIMD data in the same application. To maximize performance, programmers often used the processor exclusively in one mode or the other, deferring the relatively slow switch between them as long as possible.

Because the FPU stack registers are 80 bits wide, the upper 16 bits of the stack registers go unused in MMX, and these bits are set to all ones, which makes them NaNs or infinities in the floating point representation. This can be used to decide whether a particular register's content is intended as floating point or SIMD data.

MMX provides only integer operations. When originally developed, for the Intel_i860, the use of integer math made sense (both 2D and 3D calculations required it), but as graphics cards that did much of this became common, integer SIMD in the CPU became somewhat redundant for graphical applications. On the other hand, the saturation arithmetic operations in MMX could significantly speed up some digital signal processing applications.

I've got some 8 registers I never use, but that could be useful
for integer operations, or just to store data, or using SSE instructions
on the 64 bit area they provide.

You are right, the question is too vague, I need to express better my
idea:

Let's make a couple of practical examples:

if I run short of 32 bit GP register, how do I use the MMX registers
to store the content of some 32 bit GP register?
Is it better to push them on the stack and pop them afterwhile?
If so why?
When I have to deal with 4 16 bit integer numbers and I want
to perform some SIMD on them, like adding 1 to each of them
is it possible to do it with an MMX register?

I hope I am a little bit more clear now, I'm just trying to figure
what can I do with MMX registers that exist from 486 CPU,
without moving to X64 Assembly. It is not time yet  :P



Mind is like a parachute. You know what to do in order to use it :-)

oex

Quote from: BogdanOntanu on July 15, 2010, 05:27:48 PM
Basically when the CPU is in 32 bits mode or executes an 32 bits executable THEN x64 register are off limits even if your CPU is x64 capable.

Hey Bogdan, I was wondering is this an OS design choice or a CPU setting?.... At the lowest level (OS) you could you have switching right? rather than having to have 2 seperate exes like now but this would have to be factored into the PE equivalents design

Also does SOL OS work off PE format or do you have your own format?
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

jj2007

google for Tommesani SSE2 - best intro you can get.

frktons

Quote from: jj2007 on July 15, 2010, 05:59:00 PM
google for Tommesani SSE2 - best intro you can get.

Thanks JJ, I'll have a look.  :8)

Could anyone post some 3 lines example as well?

I mean the .686 directive to MASM is necessary?
Have I to declare some other directive for using MMX registers and SIMD/
SSE/SSE2/SSE3 instructions?

Thanks
Mind is like a parachute. You know what to do in order to use it :-)

BogdanOntanu

Quote from: frktons on July 15, 2010, 05:45:19 PM
...
Thanks, BogdanOntanu.

My machine is X64 and my OS is WIN7/64 bit, but I'm not trying
to shift to 64 bit Assembly for the time being. I'm just a beginner
so I'm going to stay on 32 bit MASM for a while.

If you already run Windows7 x64 version (I also do) then you could concentrate on 32 bits for learning and also once in a while test some x64 code  just to get your skills updated / introduced to the "new" x64 world...

At least that is what I do: I keep my main focus on x32 for now but I also do take long and deep incursions into x64 world and test programms / applications whenever I feel like.


Quote
I've got some 8 registers I never use, but that could be useful
for integer operations, or just to store data, or using SSE instructions
on the 64 bit area they provide.

Yes most of today machines have the extra MMX and XMM registers. The problem with MMX is that they are aliased over FPU registers and FPU is also releatively needed for many of today applications. If you can keep yourslef restrained into integer world then you could use MMX...

However using XMM is a much better choiche... personally I kind of ignore MMX and go directly for XMM when I want to use SSE.

Quote
You are right, the question is too vague, I need to express better my
idea:

Let's make a couple of practical examples:

if I run short of 32 bit GP register, how do I use the MMX registers
to store the content of some 32 bit GP register?
Is it better to push them on the stack and pop them afterwhile?
If so why?

Come on... such questions are naive at max. You can not gain this kind of experience by asking "what is better and why - make me a list"  kind of questions :D

First you do need to read the INTEL manuals and some tutorials (as proposed here by jj2007) on this SSE instructions.

Then try some hands on simple tests... then you will understand the basics and gain the much needed neuronal paths and experience and then you can generate much more relevant questions if you hit some road block or if no questions arise then improve your hands simple test iteratively (by adding complexity).

If you get the predigeste answer then you have data but you are not improved internally. It might be usefull in a robotic or production way but it is not usefull for your future neuronal development.

Hands on simple tests and comming back with more exact questions is a better way to learn IMHO.

However in order to hint about your questions conceptually:  
1) How do you propose to push a 64 bits register on a 32 bits stack?

2) Another thing to note is the Single Instruction Mutiple Data aspect: SSE instructions usually operate on multiple smaller data packed together inside a single MMX/XMM register. It depends on your skils to prepare or to handle data packed this way.

3) They can also help you with "saturation" and thus avoiding .IF eax>255  eax == 255 .ENDIF kind of code that can be  time consuming inside an inner loop.

Quote
When I have to deal with 4 16 bit integer numbers and I want
to perform some SIMD on them, like adding 1 to each of them
is it possible to do it with an MMX register?

Better with an XMM register ;) bu yes generally you can do this and with saturation.

Quote
I hope I am a little bit more clear now, I'm just trying to figure
what can I do with MMX registers that exist from 486 CPU,
without moving to X64 Assembly. It is not time yet  :P

x64 will give you access to extra XMM8...XMM15 but otherwise the instructions behave kind of exactly the same as in 32 bits.

Since you already use an x64 OS you do not have to restrain yourself because of this.

The real problems with X64 is that it uses another calling convention and you can not use mature enough tools yet (for example OllyDbg not working) and beeing a beginner it is of no use to deal with 2 (two) problems in the same time. You will not know if the problem is from x64 or from your handling of SSE.

However as I have said above by all means do take a peek int x64  if you are there ;)
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

clive

004014F8 0F6EC1                 movd    mm0,ecx
004014FB 0F7EC1                 movd    ecx,mm0


http://www.tommesani.com/MMXDataTransfer.html
It could be a random act of randomness. Those happen a lot as well.

BogdanOntanu

Quote from: frktons on July 15, 2010, 06:41:53 PM
Could anyone post some 3 lines example as well?

Not me :))

Quote
I mean the .686 directive to MASM is necessary?
Have I to declare some other directive for using MMX registers and SIMD/
SSE/SSE2/SSE3 instructions?

Thanks

Fast search on the forums reveals: .XMM
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

BogdanOntanu

Quote from: oex on July 15, 2010, 05:52:11 PM
Hey Bogdan, I was wondering is this an OS design choice or a CPU setting?....

It is a CPU design setting. Design choiche of AMD.

Quote
At the lowest level (OS) you could you have switching right?

Not sure what you ask... but if I guess right the answer is NO.

However you do not have to since you can run both 32bits and 64 bits executables in a 64bits OS. You just can not mix them because the CPU forbids it.

Quote
rather than having to have 2 seperate exes like now but this would have to be factored into the PE equivalents design

This is more an issue with the CPU than with PE. Hence not possible.

Quote
Also does SOL OS work off PE format or do you have your own format?

For now SOL_OS can load map and run PE32 files for compatibility reasons (with existing compilers and tools). You can also load and run plain binary files under certain circumstances (older interfaces).

However in SOL_OS you (the programmer) have full control over the machine and hence there is nothing blocking you from switching the CPU into x64 mode and use 64 bits registers and then return to 32 bits mode and /or load and run your own favorite executable.

I do plan to use my own executable format later  but this is not a priority at this moment (a format is pre-designed)

However:
1) One needs experience and deep understanding of existing formats in order to invent another "better" format.
2) There is a huge burden that a new executable format would place on potential developers and tool chains.


Note: this is kind of off-topic for the OP's question.

Hence if you intend to ask further questions on SOL_OS then you can do so on SOL_OS forums or here BUT in another thread. Emails or PM are not recommended with me :D
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

oex

ty for reply it answers my questions :)
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

jj2007

Quote from: BogdanOntanu on July 15, 2010, 07:11:09 PM

Quote
When I have to deal with 4 16 bit integer numbers and I want
to perform some SIMD on them, like adding 1 to each of them
is it possible to do it with an MMX register?

Better with an XMM register

Google for mmx fpu emms to understand the reason.

frktons

Thanks everybody.

All your suggestions will be meditated upon.  :U

what I got till now from your indications is:

1)I have to declare that I'm using MMX this way:


.686
option casemap:none
.mmx
.xmm
.model flat, stdcall


2) I can move data from 32 bit registers to the 32 low bits of an MMX
and viceversa this way:



movd    mm0,ecx
movd    ecx,mm0      


So a complete program could be:


««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««« *

   .686                                    ; create 32 bit code
   option casemap :none                    ; case sensitive
   .mmx
   .xmm
   .model flat, stdcall                    ; 32 bit memory model

   include \masm32\include\windows.inc     ; always first
   include \masm32\macros\macros.asm       ; MASM support macros

 ; -----------------------------------------------------------------
 ; include files that have MASM format prototypes for function calls
 ; -----------------------------------------------------------------
   include \masm32\include\masm32.inc
   include \masm32\include\gdi32.inc
   include \masm32\include\user32.inc
   include \masm32\include\kernel32.inc

 ; ------------------------------------------------
 ; Library files that have definitions for function
 ; exports and tested reliable prebuilt code.
 ; ------------------------------------------------
   includelib \masm32\lib\masm32.lib
   includelib \masm32\lib\gdi32.lib
   includelib \masm32\lib\user32.lib
   includelib \masm32\lib\kernel32.lib
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

start:                          ; The CODE entry point to the program

   mov     ecx, 12345
   movd    mm0,ecx
   print     str$(mm0)," value of mm0",13,10
   movd    ecx,mm0  
   print      str$(ecx)," value of ecx",13,10  
   exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start                       ; Tell MASM where the program ends



Or I still need something else? It doesn't assemble with masm32.  :(
Mind is like a parachute. You know what to do in order to use it :-)

clive

The general take away is that using MMX or SSE registers as additional scratch registers for the processor is not a great plan.

Specifically, they are designed to pull vector data out of memory and process it/them in parallel. Intel calls this SIMD (Single Instruction Multiple Data)

The Software Optimization Cookbook, Richard Gerber, Intel Press, ISBN 0-9712887-1-4
http://www.alibris.com/booksearch?qisbn=9780971288713&qwork=
It could be a random act of randomness. Those happen a lot as well.

clive

A small example that assembles.

ml  -Fl  -c  -coff  test32.asm

TEST32.ASM
        .686
        .XMM
        .MODEL FLAT

        .CODE

_start:

        mov     ecx, 12345
        movd    mm0,ecx
        movd    ecx,mm0

        ret

        END     _start


TEST32.LST
Microsoft (R) Macro Assembler Version 6.15.8803     07/15/10 15:01:09
test32.asm      Page 1 - 1


        .686
        .XMM
        .MODEL FLAT

00000000         .CODE

00000000 _start:

00000000  B9 00003039         mov     ecx, 12345
00000005  0F 6E C1         movd    mm0,ecx
00000008  0F 7E C1         movd    ecx,mm0

0000000B  C3         ret

        END     _start
It could be a random act of randomness. Those happen a lot as well.