05.1 (Conspect) C: Addressing and address arithmetic

NOTE: The server address has changed!!!

Let's talk about addressing in C

But first, let's talk about the linkers. A compiler call is a call to 5 different compilers. The linker starts the translator from assembler - from assembler to object file (ready-made machine code of the program we wrote), then the linker takes the object file and other additional files and gets the executable file - what we need - it's a special format for loading into the operating system. And so it turns out to be a ready-made program. Language C is not only an extended syntax, but also a chain of binary files.

MIPS has 30 different architectures.

The command in the terminal : as - mips32r2 -o name_your_file.o - collects files like mips

It becomes necessary to combine some system components with the functions of the executable system in C.

Trace system calls:

System Call:: is the thing that our operating system guarantees to do by itself (for MARS it is input and output, for example). The 'strace' command:: displays all system calls that our program has called. This command 'twitches' the operating system quite a lot even for those things we may not assume - memory, libraries and so on. Enter in the terminal: 'strace ./a.out' - to see the system calls that our program calls. As the result, you can see that even running a simple program calls a large bunch of system calls. Note: Discryptor 1 - standard output.

What stages and with what parameters does the compiler call when compiling the program?

enter: strace* - f -e execve cc o.c ## c -f see what kind of children and what programs they run, these are all defaults. Delete the file To run the assembler (as command), pass a huge number of parameters - from C to the assembler, from the assembler to the object file. Of all this mips32r2 is interesting. as -mips32r2 What keys did our linker call in with? There are many of them - plugin - optimization, dynamic linker - what is needed to run the program, the file is not only collected from our object (we can pass the size of the output). сrt1 crt1 crtbegin The mandatory parameter is the linker speaker. Code from all objects comes to the final file so the size becomes larger than the original one satt /-bin/lld - reduces and outputs the necessary pieces for mips

It was an excursion into the future...

And now for the address:

An address in C simply turns into a pointer, so the pointer in C is an address. For example, old Pascal has a pointer and is likely to be modeled as an address for our architecture, but Pascal doesn't say that their final number isn't written in the format - it turns out that it's just some kind of entity. In C, it says that the pointer is an address. Program example: vim

What have we got?

If you follow the logic that a pointer is just an address, exactly 4 (depending on the architecture's capacity) bytes in memory will occupy (int * A ), when int L or N - will occupy no more than 4 bytes. So, there's the code section, then there's the data section. Global variables are in memory, local variables are on the stack because they are more local and this is another placement strategy. Case variables (there is no address).

satt /usr/local/bin/compile - We get more or less read the code, we read it: In the data section - there is ASCI, string ending 0 and it has no normal label, variable str - contains the address of the place where the variable *, Carr - an array of array names in the language C - it's just labels as in the assembler. Array (words). When people program with C *str and Carr[] - different things.

How do I put in variable A which has an address, the address of variable L? - you just add one with the other and put it in A.

*Array = 100 - gets to the zero element

array[2] = 5 - this is just a number written here, the compiler can multiply 2 by 4 and load it 5 at array + 8 = because the data size is 4 bytes. Any operation with an address in the C language means to take the value at the array address - it is automatically domained to the address to which it refers. The difference is that knowing which data element our pointer points to - the C language itself can report. Few people know that 4[Array] = 10500 is quite legal, because the operation with brackets. Actually there is no indexing operation in C - this is 'syntactic sugar' over address arithmetic. It's all equivalent.

Hence the moral: remember our original language C - good macro assembler - macros, arithmetic expression and address arithmetic.

.comm - to allocate in memory some bytes with a name - so we can not initialize the array. %p - display the address in the . The address is not in the code section - &N, &L, Str, Array); L - the local variable . And the rest lie next to it in the code section. Address arithmetic also works in the delivery of composite data - a structure with 3 fields two integer and one real. Structures - we can create an array consisting of elements - structure size - 16 bytes - 4 bytes A - 4 bytes B - 8 bytes But the alignment of Alignment plays an important role - mips are arranged so that the data size which = multiple of n can not lie . Takes the biggest one and makes a multiple.

Arrays on stack

It is not recommended to start something that should turn into a local array - where will it be located ? In a data segment or stack ? The first answer seems to be in the stack... But! Check: no, not in the stack ! It's even worse than we thought. In operating memory, the compiler had to place the constants of the array with which we will initialize it - that is, it is located in data code - and the array itself is located in the stack. And a slice of code is intended to initialize it. We take the numeric shift relative to (16), load the second address and finally call the memcpy function filling the array on the stack.

Morality: DO NOT create an array on the stack - it's heavy, friend has a lot of memory!!!!!

It we want to pass the function into the function

Compiling and looking at the assembler code we see a lot of code because each function is smeared with an epilogue prologue (creates a cream does nothing), resets the frame- returns the value. In the main we put just a0 address of the function f2 - the names of the function f - just the most common labels When we put out the addresses f1 f2 ff they look like what we normally do. The beginning of the section is text. And they're lying there behind each other. Those function addresses are just their names. The array created on a function - you must tell the compiler of the c language - is an array of references to functions - remember this.


We always know what type of our pointer is. If we want, for example, to store just memory for temporary data of variables in which we will store something later, we don't know what type of data we are going to store there.

Memory was highlighted in the middle. What worries us is that mem is of int* type and malloc type - it's not clear what type. The malloc function is a system call to allocate 100500 bytes in operating memory. Then we convert it into int*. What type of address do you think the malloc function returns ? - the void* answer is a pointer to nothing. It's just an address. No size. Not subject to address arithmetic. All the memory we've allocated must be deleted.

HSE/ProgrammingOS/05_C_Addressing/Cospect_en (last edited 2020-02-12 07:05:32 by FrBrGeorge)