Although hello is a very simple program, every major part of the system must work together in order for it to complete. As we follow the life of the program, we will briefly introduce the key concepts, terminology, and components that come into play. On the other hand, integer computer arithmetic satisfies many of the known properties of true integer arithmetic.
For example, multiplication is associative and commutative, so evaluating any of the following C expressions gives On the other hand, floating-point arithmetic is not associative because of the finite precision of the representation.
A hierarquia duma arquitetura de barramentos
Hardware Organization of a System
For example, Intel Pentium systems have a word size of 4 bytes, while server-class systems such as Intel Itaniums and high-end Sun SPARCS have word sizes of 8 bytes. Controllers are chipsets in the device itself or on the system's main printed circuit board (often called the motherboard). Main memory is a temporary storage device that holds both a program and the data it manipulates while the processor executes the program.
The central processing unit (CPU), or simply processor, is the engine that interprets (or executes) instructions stored in main memory. At any given time, the computer points to (contains the address of) some machine language instruction in main memory. From the time power is applied to the system until the time power is turned off, the processor blindly and repeatedly performs the same basic task, over and over: It reads the instruction from memory which the program counter (PC) interprets the bits in the instruction, perform some simple operation dictated by the instruction, and then update the PC to point to the next instruction, which may or may not be contiguous in memory to the instruction just executed not.
Load: Copy a byte or word from main memory to a register, overwriting the register's previous contents. Store: Copy a byte or word from a register to a location in main memory, overwriting the previous contents of that location. Update: Copy the contents of the two registers to the ALU, which adds the two words together and stores the result in a register, overwriting the previous contents of that register.
Jump: Extract a word from the instruction itself and copy it to the program counter (PC), overwriting the previous value of PC.
Níveis de abstracção num computador e mecanismos de conversão
Programs are Translated by Other Programs into Different Forms (retirado de CSAPP) The hello program begins life as a high-level C program because it can be read and understood by
However, to run hello.c on a system, individual C statements must be translated by other programs into a sequence of low-level machine language instructions. Here, the GCC compiler driver reads the hello.c source file and compiles it into an executable hello object file. The compiler (cc1) translates the text file hello.i into the text file hello.s, which contains the assembly language program.
For example, C compilers and Fortran compilers both generate output files in the same assembly language. Then the assembler (as) translates hello.s into machine language instructions, packages them into a form known as a movable object program, and stores the result in the hello.o object file. The hello.o file is a binary file whose bytes encode instructions in machine language instead of characters.
If we viewed hello.o with a text editor, it would be nonsense. The printf function is contained in a separate precompiled object file called printf.o, which must somehow be merged with our hello.o program. For simple programs like hello.c, we can rely on the compilation system to produce correct and efficient machine code.
We will describe stack discipline and buffer overflow faults in Chapter 3 as part of our study of assembly language.
Processors Read and Interpret Instructions Stored in Memory
In Chapter 3, we will introduce the Intel IA32 machine language and describe how compilers translate various C constructs into that language. In Chapter 5, you'll learn how to tune the performance of your C programs by making simple transformations to the C code that help the compiler do its job. And in Chapter 6, you'll learn about the hierarchical nature of the memory system, how C compilers store data arrays in memory, and how your C programs can take advantage of this knowledge to run more efficiently.
In our experience, some of the most confusing programming errors are related to the operation of the linker, especially when trying to build large software systems. For example, what does it mean when the linker reports that it cannot resolve a reference. And most frightening of all, why do some linker-related errors not appear until runtime.
For many years now, buffer overflow errors have accounted for the majority of security holes in network and Internet servers. These errors exist because too many programmers are unaware of the stack discipline that compilers use to generate code for functions. The operating system achieves both goals via the basic abstractions shown in Figure 1.11: processes, virtual memory, and files.
As this figure suggests, files are abstractions for I/O devices, virtual memory is an abstraction for both main memory and disk I/O devices, and processes are abstractions for the processor, main memory, and I/O devices.
Running the hello Program
The operating system has two primary purposes: (1) to protect the hardware from abuse by rogue applications, and (2) to provide applications with simple and uniform mechanisms for manipulating complex and often very different low-level hardware devices. When we press the Enter key on the keyboard, the shell knows that we are done with the command. The shell then loads the hello executable by executing a series of instructions that copy the code and data in the hello object file from disk to main memory.
The data includes the string of characters "hello, world\n" which will eventually be printed. Using a technique known as direct memory access (DMA, discussed in Chapter 6), the data goes directly from disk to main memory without passing through the processor. Once the code and data in the hello object file are loaded into memory, the processor begins executing the machine language instructions in the hello program's main routine.
These instructions copy the bytes in the string "hello, world\n" from memory to a register file and from there to the display device where they are displayed on the screen.
Execução de instruções num computador
- Acessos à memória na execução de instruções
- Accessing Main Memory (retirado de CSAPP)
- Instruction-Level Parallelism (retirado de SCO)
- Caches Matter (retirado de CSAPP)
- Storage Devices Form a Hierarchy (retirado de CSAPP)
Data flows back and forth between the processor and main DRAM memory through shared electrical channels called buses. The main components are the CPU chip, a chipset we'll call the I/O bridge (which includes the memory controller), and the DRAM memory modules that include the main memory. These components are connected by a pair of buses: a system bus that connects the CPU to the I/O bridge and a memory bus that connects the I/O bridge to main memory.
Next, the main memory registers the address signal on the memory bus 10, reads the address from the memory bus, fetches the data word from the DRAM, and writes the data to the memory bus 11. Finally, the CPU registers the data on the system bus, reads it from the bus, and copies it to register %eax (Figure 6.7(c)). Finally, the main memory reads the data word from the memory bus and stores the bits in the DRAM (Figure 6.8(c)).
As with a single pipeline, the compiler must ensure that this situation is maintained (i.e. the hardware does not check and returns incorrect results if the instructions are not compatible), or conflicts are detected and eliminated at runtime using additional hardware. As the processor executes the program, instructions are copied from main memory to the processor. Similarly, a typical registry file stores only a few hundred bytes of information as opposed to millions of bytes in main memory.
A process may take 5 times longer to access the L2 cache than the L1 cache, but this is still 5 to 10 times faster than accessing main memory.
Análise do nível ISA (Instruction Set Architecture)
- Operações num processador
- Formato de instruções em linguagem máquina
- Tipos de instruções presentes num processador
- Registos visíveis ao programador
- Modos de acesso aos operandos
- Instruções de input/output
- Caracterização das arquiteturas RISC (resumo)
Quando os custos de memória e processador eram altos, os conjuntos de instruções do processador eram compactados em pequenas dimensões (8 bits) ao custo de comprometer o número de operandos a serem incluídos e o uso de instruções de comprimento variável (com consequências desastrosas para o desempenho do pipeline). ). As arquiteturas RISC tinham como um de seus objetivos a definição de formatos de instrução com comprimento e tamanho fixos que permitissem especificar 3 operandos: 32 bits. As figuras a seguir ilustram os 2 tipos de instruções mencionadas acima: uma vem da arquitetura dos anos 1970 (Pentium II baseado no 8086/8) e a outra da arquitetura RISC (MIPS).
O conjunto de instruções presente no conjunto de instruções de cada processador (ou família de processadores) é bastante variado. Nas arquiteturas RISC, as operações aritméticas/lógicas exigem que os operandos estejam nos registradores da CPU: seja nos registradores especificados pelo programador (um dos 32 registradores genéricos, ou fp), seja no registrador da instrução (como parte do formato de instrução, também conhecido como modo de acesso instantâneo). O acesso à memória em arquiteturas RISC geralmente é feito por meio de operações de carregamento ou armazenamento.
Nessas operações, as arquiteturas RISC normalmente especificam um endereço de memória (para uma instrução load ou store) de apenas uma maneira: um valor numérico de 16 bits e um registrador; a posição de memória acessada é dada pela soma desse valor com o conteúdo do registrador especificado. Algumas arquiteturas RISC também suportam, alternativamente, o cálculo de endereços através da soma do conteúdo de 2 registradores. O tamanho de cada célula de memória (8 bits) não é grande o suficiente para armazenar totalmente o conteúdo de um registrador (32 bits).
Algumas arquiteturas RISC suportam ambas, mas apenas uma de cada vez quando a CPU é reinicializada. Para executar essas atividades, a maioria dos processadores não possui instruções de entrada/saída específicas; apenas use as instruções normais de acesso à memória para ler ou escrever os registradores do controlador. Outros processadores, como os da família Ix86, também possuem instruções de I/O específicas, que implementam essencialmente uma das 2 operações de acesso a um registrador do controlador (também chamado de porta): a função de ler uma porta - em - ou por escrito em uma porta - fora.
Anexo: Arquitetura e conjunto de instruções do IA-32