What are recorders and what is their basic functioning?

Asked

Viewed 12,436 times

7

I am reading a book about Assembly in order to better understand how a low-level language works, it will help me to understand more effectively the internal functioning of the programs I develop in C. And in a given passage, the book mentions the registers, see:

Registers are named Storage Locations in the CPU that hold Intermediate Results of Operations.

There is also an example of a code in C++ and Assembly, see:

In C++:

int Y;
int X = (Y + 4) * 3;

In Assembly:

mov   eax,Y
add   eax,4
mov   ebx,3
imul  ebx
mov   X,eax

In the above quote it says that they are a data storage location in the CPU, however, I still can’t understand what is actually a logger and how important it is for the operation of the program. Therefore, the doubts that arose are addressed below.

Doubts

  1. What in fact are recorders?
  2. How is the basic functioning of a register?
  3. What is the importance of registrars in relation to programs I develop?
  4. Is there any relationship between RAM memory and registers?

The book I’m reading is Assembly Language for x86 Processors (Sixth Edition).

  • 3

    In other times this would give dozens of votes, but now let’s hope for 10 :)

3 answers

8


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:

  • I could understand yes, however, as we ask and get answers, more questions will arise, of course in the future I will ask more specific questions regarding these questions, linking with this question. And the answer showed me a way and how I can continue studying and clarified the "mystery" of the recorders, which of mysterious has nothing ;)

4

What are Registers?

Are pieces of logic circuits of specific end capable of storing values to be worked out next.

You can have whole, floating point registers with 16, 32, 64 bits (other bites are accepted), etc.

They are named to be easily rescued in machine code. For example, in Assembly add eax, 4 refers to a command (add) being applied on a register (eax) and keeping the result right there. You might as well have done add ebx, 4, which is almost the same Assembly instruction, but would be another command for the processor of any sort.

How is the basic functioning of a register?

A worthy CPU has at least two parts: the arithmetic logic unit (ULA), to make computations with integer numbers; and the controller unit (UC), which is simply responsible for moving the information from one register to the other, or taking from memory, or returning to memory; it is also UC that is responsible for getting everything ready for ULA to compute. And it’s the UC that keeps pointing out which registers to compute.

In the basics, registers function as an electrical circuit that maintains its state (each bit is a state) until two external signals arrive and it needs to change signal. The first external signal really is the next desired value to occupy for each bit. But that alone is not enough: an extra signal is also needed to say "make the exchange".

Yeah, but what’s the practical use of it?

Well, with that you can do computations. A ULA is just a logic circuit that can be replaced with a black box, as if it were a logic gate with 3 inputs and a main output:

  • (in) left operand
  • (in) operating right
  • (in) transaction code
  • (out) result of the operation

For ULA, it does not matter in any way the origin of the inputs: it will simply interpret them as electrical signals and, about this, will offer the result.

So the function of the registrar is basically to be an information repository that the UC will call on the inputs and outputs of the ULA in order to do a computation and save its result.

In addition to this primary function, loggers also store memory region pointers that can be accessed. In this case, the recorder will be rescued by the UC itself to access some memory region. You did not set example of this use.

What importance do registrars have in relation to the programs I develop?

Sincerely? Difficult to answer this question without knowing which ones programs are those. Normally you will not worry about this when using a fifth-generation language due to its remoteness from the CPU. But some concepts can make a tremendous difference: temporal locality (in this case, not spatial).

What is locality? Some authors discuss the subject:

In short, it is the possibility of reusing data cached.

When you design your program so that it makes it easier for the compiler to optimally allocate each variable in the perfect register, you would only have to spend on control operations to take the values of the working memory and put them on the registers and vice versa. However, if you have not facilitated the life of the compiler, you can force it to always, every operation performed, take the values of memory, by the recorders, turn the result to memory and take the next operands.

As if its multiplication came from:

mov   eax,Y
add   eax,4
mov   ebx,3
imul  ebx
mov   X,eax

For something like this:

mov   eax,Y
add   eax,4
mov   Y,eax
mov   ebx,3
mov   eax,Y
imul  ebx
mov   X,eax

Noticed that it was forced here to move the sum result to memory (mov Y,eax)? And he noticed that then I needed to take the value that was in memory and get it ready for use in multiplication (mov eax,Y)? In the original version this was not necessary because the operand was already "in place" for that moment of time. This can deeply affect your program’s performance.

Even so, the temporal locality would have an effect on L3 cache.

Normally I use much more the spatial locality than the temporal one, that it affects more my life.

It has another controversial aspect as well: recorder is not the only paradigm of making Assembly operations. It also has the stack machine (not the stack automaton, do not confuse) that does not use registers for anything. The JVM, for example, is a stack machine, whereas the old Dalvik is a register machine. There are studies about the performance of battery machines versus register machines, but I can’t remember if they’ve reached any consensus or if it’s still debated.

Is there any relationship between RAM memory and registers?

Yes. The data is in the RAM, due to its size and range. It is as if it were the tape of the Turing machine. The registers contain only the information that will be operated almost instantaneously. As if things were read by the heads of the Turing machine.

As in the Turing machine, you are unable to operate on things that are out of your head, so you are not able to operate on RAM. In compensation, you can transport the head to the appropriate locations and read this information (transferred from the RAM to the register), or write on the tape the new information (transferred from the register to the RAM).

  • The 3 entries that go to ULA would be 4 (left operand), 1 (operating right), 231 (transaction code corresponding to the addition operation +), 5 (result of the operation). The 3 input data comes from the registers (which were previously allocated in the RAM) and when the data is computed it returns to some register and then returns to the RAM. This line of reasoning is correct?

  • 1

    ULA will care neither about the source nor the destination of the data. This is UC’s concern. It will "connect the wires" with what is needed. And the operation comes from the instruction being processed, which the UC will translate into the ULA properly

2

  1. The registers are a "space" within the (micro)processor where it is possible to store certain values. These can be an arbitrary value, the result of a logical/arithmetic operation, flags status or memory addresses for the next statement to run or register stack position (stack) in memory RAM.

    • Keep in mind that processors do not directly manipulate memory (usually they only recover or store values), everything else needs to be done within them.
  2. From the point of view of Assembly they function as variables, where you make a a = 10 in a language you make LD A,10 (or MOV A,10) to store a value. The difference is that a programming language allows you to create as many variables with which type and size you want while the number and size of the registers is defined during the processor design (by the way, we call a, a', eax, r0, etc but are conventions).

  3. The programming languages abstract the registers and usually do not make direct assignments (the example you showed is a translation, the compiled version does not look anything like that), type of register size and unless you will program directly into Assembly it won’t make much difference.

  4. No, the registers are part of the processor (physically speaking) while the RAM is an external component. For this reason accessing the value of a register is absurdly faster than accessing the same value stored in RAM.

There is a 2011 presentation of Chaos Communication Congress, about reverse engineering on MOS6502, which may help. There you can "see" the recorder... :-)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.