TL; DR
What in fact are Recorders?
They are memory positions within the processor with specific names, it is as if they were variables.
How is the basic functioning of a Registrar?
They are addresses that store data for a short time (it could be long, it just doesn’t make sense) so that the processor can manipulate this data or use it to manipulate some other data. Even some serve to control the fundamental functioning of the processor or the execution of your code, in general things that you do not even know if there is.
What is the importance of Registrars in relation to the programs I develop?
Nothing in the abstract sense that you deal with. Everything concretely. It is only in them that there is actual execution and they are much faster than the memory where you think your data is running.
Is there any relationship between RAM and Recorders?
They are a type of short-term memory. The only relationship with RAM is that they talk to each other all the time. Regarding the data loggers comes and goes from and to the RAM.
Detailing
That’s basically what’s in the :P definition
Memory you know? And variable?
Memoriam
Memory is composed by several slots and we can say that always a slot is 1 byte in size. Access to each slot is done by a number, because it has a large amount of it. Think of memory as a huge array of bytes.
Some of these slots can be accessed together and it is possible to give a name to access some of them in specific during the creation of the code, but in fact the access is done by the number, even if you see it in it.
Recorders
The registers are no longer a memory, but with special features and in very low number, because the distance that the electrical signal needs to travel needs to be very small to happen very fast. If they had many registers most of them would stay away and the access time would be greater.
Unlike normal memory, each slot in this memory inside the core of the processor has a slightly larger size, we usually call this word. So on 32-bit processors this size is 4 bytes and a 64-bit size is 8 bytes. But there are special registrations with different sizes, some are 1 bit because it doesn’t need more than that, and others may have several bytes to process special actions in vectors, encryption, etc.
It’s still a place where bits are stored for a while, usually very little time, in up to 1 or a few cycles. As they are few can have a name. But like everything in Assembly, they didn’t give names that easy. And since it is not a specific task as it occurs in a normal code of an application the names are very generic. But we can say that they are the low-level variables of any code.
Keeping the analogy I made with memory understand them as a large object with several named members, would be defined as a class or a structure.
Operations
All operations the processor can perform are on top of the registers. It is not possible to manipulate the RAM directly, you have to move the information to the register to manipulate and then you can move the result to the RAM again, if that is what you want.
The logic ports that perform something by taking the bits present in one or two registers (have special instructions that can pick up more data, are called SIMD) and turning into another bit(s) that must enter into some register(s) (s).
Performance
Access to a register on an x86 processor costs around the corner. It is possible to access 3 or 4 billion accesses per second. An ARM doesn’t get far behind that. Access to RAM costs almost 100 nanoseconds (it has dropped a little), so about 10 million accesses per second. It’s a brutal difference.
That is why it is important to keep the data in the register. And that is why in the past writing Assembly helped a lot. Today compilers tend to make better choices than humans in many cases and puts what is most important in the register.
Note that the access time is not the same as a manipulation operation. A split for example can cost several nanoseconds even accessing only the register.
Abstraction
Everything you write in high-level language that touches a data will pass through a recorder.
This Assembly code is a little high level because the variables X and Y do not exist in the context of Assembly, there would be pure memory addresses (in the case of stack).
Limiting
You may be imagining that because there are few registers (16 main ones in the most common cases) what to do when you are working with many variables (even conceptually speaking). You send to memory what does not fit in the processor at that time. In practice this occurs naturally because you put some data in the main registers, run something and get the result sending to memory.
Cache
The processor has a legal abstraction that it can keep certain data very much cached, the famous L1, L2, L3 and late L4 that are small are closer to the processor and have much better access times than RAM. And distance is the reason it has multiple levels.
In a certain point of view the register is a kind of cache too, where the memory would be like the file of swap of the operating system, is there to ensure that everything works with large volumes, but it is better to avoid its use.
I could even talk about the new non-volatile memories that will make RAM persist data, or I could talk about the cache line where data is always transferred in block, so accessing 1 byte or 64 (typically) costs almost the same, but this escapes a little from the focus.
Existing recorders
There are 4 main registers on an Intel x86 processor that are called EAX, EBX, ECX, EDX. In 64 bits the names are RAX, RBX, RCX, RCX and obviously the sizes are larger. As curiosity in 16 bits they are called AX, BX, CX, DX, and they can be accessed at each individual byte in its low or high part, so there’s AL and AH, BL and BH, and so on.
Remember these are just names as if they were variables, there is not much secret. And we can say that they have only one type, which is the word. Almost everything is done in these registers. The most common, but only by convention are:
- EAX used as an accumulator (receives transaction results)
- EBX would be used as a basis for operations
- ECX is an accountant (increasing something)
- EDX acts as general data to be used in the operation.
Other very important registers used all the time in every application that are considered for general use but that are almost always used for something very specific are:
- ESP (Stack Pointer - indicator of where the end of the stack is in memory)
- EBP (Base Pointer - indicator of where the scope is now, the accesses to the data in the stack are always relative to that address, in general it indicates the beginning of the data of the running function, so there is an arithmetic in each access to a given)
- ESI (Source, sometimes called index)
- EDI (Destination, the latter are used by optimized multi-data access instructions such as arrays, including strings)
Remembering that in 64 bits they start with R.
Then we have special segment recorders that there is no practical use nowadays with the advent of virtual memory.
One of the most important registers is the EIP or Instruction Pointer. He’s the one who knows where the code is running. Each instruction that ends its run increments to the next execution address that the code should perform, which is variable on Intel-like processors, but has fixed size on RISC processors as is the ARM. A goto
(jmp
) among other instructions manipulate this address by deviating to a specific address totally outside the sequence.
In 64 bits we have the R8 at the R15 that are complementary registers and function as the first, but with nothing more conventional for use and are used as optimizations, in simple operations they tend to be empty (conceptually since it will always have given that was there).
I did not speak of special registers used by MMX, Ssex, etc. instructions because I do not understand them well and I think it is not the case of most uses.
Finally we arrived at the bit registers (flags) that receive certain control results and are consulted in certain instructions to decide what to do. You can imagine that scrolling in many comparison instructions, but not only, even in arithmetic can scroll a lot. These registers are updated in most operations, so you only have the last state, if you need this information for some later operation (usually you don’t need it) then you should store it somewhere, whether it’s a general register or in memory. I won’t list them all, but the main ones are (bit addresses):
- 00 CF - Carry Flag - is the famous "go one" (yes, the computer needs to account for the way you’ve always done since you were a child)
- 02 PF - Parity Flag - indicates whether the result is even or odd, which allows some optimizations
- 04 AF - Adjust Flag - used for calculation BCD, unimportant these days
- 06 ZF - Zero Flag - control whether the operation resulted in 0 (false)
- 07 SF - Sign Flag - indicates if the operation has a negative sign or not
- 08 TF - Trap Flag - step control Debugger
- 09 IF - Interruption Flag - indicates if interruptions are allowed (responding events)
- 10 DF - Direction Flag - direction control strings
- 11 OF - Overflow Flag - indicates that there was overflow in operation (the result does not fit in the placeholder)
- 12-13 IOPL - I/O Privilege Level field - indicates the level of privilege the operation can perform, some only the kernel of the SO may perform
- 14 - NT - Nested Task flag - interrupt chaining control
- 16 - RF - Resume Flag - control of Debugger
- 17 - VM - Virtual-8086 Mode - establishes compatibility mode
- 18-31 - modern virtualization and identification indicators
- 1, 3, 5, 32-63 - reserved
Your code:
mov eax,Y
- It is moving to the register called EAX the value that is in memory at a certain address that is conceptually indicated by Y
add eax,4
- You are doing an addition operation between the value that is in EAX and constant 4, obviously the result will change some bit registers and keep the result in EAX even, so it is a side effect operation to what is being used in the calculation
mov ebx,3
- It’s storing the number 3 in the EBX register, it’s like making a ebx = 3;
imul ebx
- It is performing a multiplication of integers, which is simpler than a floating point using the EBX multiplier, the multiplication is implicitly the EAX, and the result will be stored in EAX, as usual
mov X,eax
- It is moving to what is called conceptually X (in practice it is a memory address) which is stored in EAX at this time.
Typically this can take a hundred and so many nanoseconds to perform. And just over 2 or 3 nanoseconds is the calculation itself. That’s why I say optimize is not accessing memory, is not saving processing itself. Doing everything that needs to be on the processor and operate on the processor and being able to prevent loggers from being used superimposed on a processing line do far more for performance than saving processing instructions or using instructions with fewer cycles of cost.
Because every time you need to use the EAX for example, and it is busy, you have to play to memory what you have there (stack) in order to be able to use it without problems and after finishing this new operation has to return the value saved before in the stack to the register to continue what it was doing. Even if the stacking occurs in the L1 cache costs a lot more expensive not only because it is an extra operation only control, but also because it costs expensive.
One of the reasons one tries to do inline function is because there is a lot of data copy from register to memory and vice versa in function calls.
Contrary to what people think, Assembly is not that difficult, it’s boring, it’s weird, you have to be very careful, but it has low complexity and little abstraction that makes understanding difficult. In fact if they adopted a syntax a little better it would scare less. But of course, as well as in C the access to heap or use of pointers already scares because it is easy to make mistakes and melar the memory, in Assembly any access scares general.
Might be of interest:
In other times this would give dozens of votes, but now let’s hope for 10 :)
– Maniero