Program. Datorteknik. Semantiskt gap. C - Inledning. Abstraktionsnivå: Högnivåspråk. Assemblyspråk. Maskinspråk

Relevanta dokument
Datorteknik ERIK LARSSON

Datorteknik ERIK LARSSON

Datorteknik ERIK LARSSON

Datorteknik ERIK LARSSON

Översikt. Datorarkitekturer med operativsystem. Inledning. Inledning

Minnets komponenter. Digitala System: Datorteknik. Programexekvering. Programexekvering. Enhet för utdata. Enhet för indata CPU.

Fö 7: Operativsystem. Vad är ett operativsystem? Målsättning med operativsystem. Styr operativsystemet datorn?

Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??

En Von Neumann-arkitektur ( Von Neumann-principen i föreläsning 1) innebär:

Tentamen den 12 januari 2017 Datorarkitektur med operativsystem, EDT621

TDDIU81. Processer och trådar. Andreas Dahlberg, Jonathan Doherty, Tony Magnusson, Patrik Ottosson, Rasmus Siljedahl

Datorarkitekturer med operativsystem ERIK LARSSON

Minnet från processorns sida Datorteknik

Fö 5+6 TSEA81. Real-time kernel + Real-time OS

Datorarkitekturer med operativsystem ERIK LARSSON

Vad är en dator? Introduktion till datorer och nätverk. Pontus Haglund Institutionen för datavetenskap (IDA) 21 augusti 2018

Enkla datatyper minne

Datorarkitekturer med operativsystem ERIK LARSSON

Datorteknik ERIK LARSSON

Program Datorteknik. Kontrollenhet. Exekvering av en instruktion. Abstraktionsnivå: Högnivåspråk. Assemblyspråk. Maskinspråk.

Digitala System: Datorteknik ERIK LARSSON

TDIU01 - Programmering i C++, grundkurs

Datorsystemteknik DAVA14 Föreläsning 10

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

Programmering av inbyggda system. Kodningskonventioner. Viktor Kämpe

DVG A06. Operativsystem, mm. Karlstads universitet Datavetenskap. DVG A06 Johan Eklund. Datavetenskap, Karlstads universitet 1

Operativsystem. Informationsteknologi sommarkurs 5p, Agenda. Slideset 7. Exempel på operativsystem. Operativsystem

Grundläggande datavetenskap, 4p

Operativsystem. Innehåll. Operativsystemets funktion. Vad är ett OS? Vart hittar men ett OS? OS hanterar processorns resurser

Dagens OS. Unix, Linux och Windows. Unix. Unix. En översikt av dagens OS Titt på hur de gör. Många varianter Mycket gemensamt. En del som skiljer

Översikt Introduktion DST 1. Nicholas Wickström. IDE, Högskolan i Halmstad. N. Wickström

Närliggande allokering Datorteknik

Operativsystem DVG A06. Definition. Varför operativsystem? - Vad är ett operativsystem?

Lågnivåprogrammering. Föreläsning 2 Lågnivåprogrammering. Binära tal. En enkel modell av datorns inre

Datorteknik ERIK LARSSON

*Pekarvärden *Pekarvariabler & *

Fö 8: Operativsystem II. Minneshantering. Minneshantering (1) Minneshantering (2) Minneshantering och Virtuelltminne.

Definition DVG A06. Varför operativsystem? Operativsystem. Översikt. - Vad är ett operativsystem?

Institutionen för elektro- och informationsteknologi, LTH

Datorteknik. Föreläsning 5. Realtidssystem och realtidsprogrammering. Institutionen för elektro- och informationsteknologi, LTH.

Svar till tentamen den 16 december 2013 Datorarkitekturer med operativsystem, EDT621, 7,5 poäng

Outline. Datorsystemtekni. Kravspecifikation. Kravspecifikation (forts.)

Mål. Datorteknik. Repetition av avbrott. Innehåll. Mätning och styrning. Datorer för mätning och styrning. timer. Datorsystem A/D. Analog insignal D/A

Operativsystem (ID2200/06) XX XX:00-XX:00

Tentamen den 18 mars svar Datorteknik, EIT070

Lathund. C för inbyggda system

AVR 3 - datorteknik. Avbrott. Digitala system 15 hp. Förberedelser

Olika OS. Unix, Linux och Windows. Unix. Unix. En översikt av ett par OS. Titt på hur de gör. Många varianter. Mycket gemensamt. En del som skiljer

Operativsystem Lektion 1. Lärare. Schema. Kurssajten Finns på adressen. Jan Erik Moström. Set Norman

SVAR TILL TENTAMEN I DATORSYSTEM, VT2013

Operativsystem - input/output, skydd, virtualisering

Per Holm Lågnivåprogrammering 2014/15 24 / 177. int och double = = 2, 147, 483, 647

F5: Högnivåprogrammering

TDIU01 - Programmering i C++, grundkurs

F5: Högnivåprogrammering

Exempeltentamen Datorteknik, EIT070,

Datorsystem 5. På denna föreläsning skall vi prata om Operativsystem Exempel på tenta (typ fjolårets)

Operativsystem ID1200/06 (ID2200/06 6hp) Tentamen :00-18:00

Tentamen den 14 januari 2016 Datorarkitektur med operativsystem, EDT621

Elektroteknik MF1016 föreläsning 9 MF1017 föreläsning 7 Mikrodatorteknik

Datorsystem. Laboration 3: Operativsystem Senast uppdaterad: 14 oktober 2012 Version 1.3. Student: Underskrift: Underskrift: Datum:

Datorsystem 2 CPU. Förra gången: Datorns historia Denna gång: Byggstenar i en dators arkitektur. Visning av Akka (för de som är intresserade)

Operativsystem (IS1350) :00-12:00

Datorteknik 2 (AVR 2)

Digitala System: Datorteknik ERIK LARSSON

Datorarkitekturer med operativsystem ERIK LARSSON

Att använda pekare i. C-kod

Program kan beskrivas på olika abstrak3onsnivåer. Högnivåprogram: läsbart (för människor), hög abstrak3onsnivå, enkelt a> porta (fly>a 3ll en annan ar

Introduktion C-programmering

Datorarkitekturer med operativsystem ERIK LARSSON

Repetition C-programmering

C-programmering. Målsättning Introducera programmering i C för de som inte har någon erfarenhet av C eller C++. Litteratur

Operative system. LRU-algoritm (2 p) Svar: 7 fel. c) Optimal algoritm (2 p) Svar: 6 fel

IT för personligt arbete F5

F2: Motorola Arkitektur. Assembler vs. Maskinkod Exekvering av instruktioner i Instruktionsformat MOVE instruktionen

Digitala System: Datorteknik ERIK LARSSON

En kort text om programmering i C.

F4. programmeringsteknik och Matlab

En processor kan ha en klockfrekvens på flera GHz. Det går alltså a9 exekvera en instruk=on väldigt for, givet a9 instruk=onen finns i processorn.

Lösningar till tentamen i EIT070 Datorteknik

Klassdeklaration. Metoddeklaration. Parameteröverföring

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

Programmering A. Johan Eliasson

Föreläsning 10. Pekare (Pointers)

Operativsystem. Hierarkin för hårdvara läses nerifrån

Tentamen i Digitala system - EDI610 15hp varav denna tentamen 4,5hp

System S. Datorarkitektur - en inledning. Organisation av datorsystem: olika abstraktionsnivåer. den mest abstrakta synen på systemet

Hantering av textsträngar och talsträngar. William Sandqvist

Operativsystem ID2200 Tentamen TEN1 3.8 hp :00-18:00

Realtidsstöd i Minix. En laborationrapport. Oktober 2012

Programmering i C. Vad är C? Målsättning. Litteratur. Jämförelse med Java. Exempel : Ett program som skriver ut texten Hello, world

Tentamen PC-teknik 5 p Lösningar och kommentarer

Flera processer. Minneshantering. Trashing kan uppstå ändå. Ersätta globalt

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Tentamen. Datorteknik Y, TSEA28

Systemkonstruktion LABORATION REALTIDSPROGRAMMERING

Institutionen för elektro- och informationsteknologi, LTH

Datorteknik. Föreläsning 2. Programmering i C och assembler MIPS instruktionsarkitektur. Institutionen för elektro- och informationsteknologi, LTH

TDDC77 Objektorienterad Programmering

Föreläsning 3: Booleans, if, switch

Transkript:

Datorteknik ERIK LARSSON Program Abstraktionsnivå: Högnivåspråk» t ex C, C++ Assemblyspråk» t ex ADD R1, R2 Maskinspråk» t ex 001101.101 Semantiskt gap C - Inledning Alltmer avancerade programmeringsspråk tas fram för att göra programvaruutveckling mer kraftfull Dessa programmeringsspråk (Ada, C++, Java) ger högre abstraktionsnivå, konsistens och kraft Det semantiska gapet ökar (högnivåspråk-maskinspråk) Abstraktionsnivå Högnivåspråk Maskinspråk Semantiskt gap Ken Thompson och Dennis M. Ritchie utvecklade C Turingpriset( Nobelpris i datavetenskap ), 198 Alan Turing (1912-19) För deras utveckling av generellt OS teori och speciellt för deras implementation av operativsystemet UNIX

Datatyper Datatyper Datatyp Antal bytes Talområde unsigned char 1 0 2 signed char 1-128 127 unsigned int 2 0 signed int 2-278 277 unsigned long int 0 299729 signed long int -21788 21787 float ±1,18 E-8,9 E+8 char Tal, Max, Min; Exempel: Tal=; unsigned int Adress; Exempel: Adress=12; const char Tabell [][] = {{ 2, 0,, { 12, 1, 1, { 2,, 8, { 29, 2, ; Exempel: Tabell[1][1]=2; const char String [] = "ABC"; Datatyper Samma sak lagras: char a = ; decimalt char a = 0x1; hexadecimalt char a = 0b01000001; binärt char a = A ; ASCII-kod Datatyper Exempel: Binärt värde av c1=; /* c1 har bitmönstret 00000101 */ c2=; /* c2 har bitmönstret 00000110 */ Address Instruction/Data 00001000 01000001 00001001 00011011 00001010 00101000 00001011 00010011

Tilldelningssatser Aritmetiska operationer Deklarera variabel: unsigned char a; a: Operationer: + addition CPU Kontrollenhet Tilldela variablen ett värde: - subtraktion a = ; Addera 2 till värdet i a: a: * multiplikation / division Aritmetisk Logisk Enhet (ALU) a = a + 2; a: 7 % Modulodivision OP IN 1 UT ALU IN 2 Status Beräkningar Bithantering unsigned char a, b, c; Exempel: Och (AND): & Eller (OR): CPU Kontrollenhet a=; Exklusivt eller (XOR): ^ b=10+a-; c=a*b; Invertering (NOT): ~ Vänstershift: << Aritmetisk Logisk Enhet (ALU) a=b 20; b++; // bitvis eller (or) //samma som b=b+1 Högershift: >> UT OP ALU IN 1 IN 2 Status

Bithantering Villkor Exempel: c1=; /* c1 har bitmönstret 00000101 */ c2=; /* c2 har bitmönstret 00000110 */ c9=~c1; /* c9 får bitmönstret 11111010 */ c10=c1<<; /* c10 får bitmönstret 00101000 */ c11=c1<<; /* c11 får bitmönstret 01000000 */ c12=c1>>2 /* c12 får bitmönstret 00000001 */ c1=c1&c2 /* c1 får bitmönstret 00000100 */ c1=c1 c2 /* c1 får bitmönstret 00000111 */ if ( villkor ) sats; Exempel 1: Exempel 2: int n if ( n == 27 ) { din kod här int n; if ( n == 27 ) { din kod om talet var 27 else { din kod om talet inte var 27 Villkorsuttryck Villkorsuttryck Om a= så öka a med 1: if (a == ) a = a +1; Villkor: // if (villkor) sats; == lika med, > större än, < mindre än,!= inte lika med Om a=10 så öka a med 2 i annat fall minska a med : if (a == 10) a = a + 2; else a = a ; Så länge a< öka b med : while (a < ){ a = a + 2; b = b + ;

Loopar Alternativ: while (uttryck) sats; do sats; while (uttryck); for (initiering; styruttryck; stegning) sats; Exempel 1: int n=1; while ( n++ <= 10 ){ din kod Exempel 2: int n; for ( n=1; n <= 10; n++ ) { din kod här Funktioner All kod paketeras i funktioner. Huvudprogrammet: void main(void) { b = + my_funktion(); En funktion deklareras: int my_funktion(x) int x { return (x+2); Funktionsanrop Inparameter Datatyp som returneras Gör/skapar retur värdet Funktioner Pekare (Intro) i: 78 Exempel: Funktionen kvadrat beräknar: y=x*x kan se ut: int kvadrat(x) int x { return x*x; Anrop: y=kvadrat(); //y blir 9 Värdet av x skickas in och funktionen returnerar kvadraten. Deklarationen: int i, i Ger att: i och i är heltalsvaribler Exempel: i=78; //sätter i till 78 i= //sätter i till Låt i vara lagrat på adress 0 Låt i vara lagrat på adress 1 i: 0 (i) 78 1 (i) 2

Pekare &i i: 78 Pekare Deklarationen: ip1: int i, i, *ip1, *ip2; Ger att: *ip1 och *ip2 är heltalspekarvariabler i och i är heltalsvariabel Exempel: i=78; //sätter i till 78 ip1=&i //sätter ip1 att peka på adress där i finns & ger adressen till något Notera: ip1 har plats för en pil (adress) och i har plats för ett heltal 0 (i) 78 1 (i) 2 (ip1) (ip2) Exempel: Deklarationen (samma som innan): int *ip1, *ip2, i, i i=78 ip1=&i ip2=ip1 //ip2 sätts att peka på samma som ip1 ip1: ip2: &i i: 78 Pekare Pekare Exempel: Deklarationen (samma som innan): int *ip1, *ip2, i, i i=78; ip1=&i; ip2=ip1; i=*ip1; //i sätts till det heltal som ip1 pekar på *ip1 består av två steg. Först, tas ip1: pekaren fram. Sedan, via *, tas värdet till pekaren fram i: 78 ip2: &i i: 78 Precis som andra variabler, blir pekare inte automatiskt tilldelade ett värde vid deklaration. För att sätta en pekare att peka på ingenting: ip=null; Sätts inte en pekare att peka på ingenting kan den peka på vad som helst det som råkar ligga på den minnesplatsen. ip: X

Pekare till funktioner Exempel 1:Fråga Om, parametern är en pekare.. Exempel: void kvadrat(xref) int *xref { *xref= *xref * *xref; Anrop: kvadrat(&x); 0 (a) 10 1 (b) 2 xref x är ett pekarvärde. Funktionen tar värdet av pekaren, gör kvadrat och updaterar pekaren Komplettera koden nedad så att värdet i variabel a och b byter värde. void main (void){ int a, b; // deklaration av värde a = 10; // a tilldelas värde b = ; // b tilldelas värde? // kod för att a och b // byter värde 0 (a) 10 1 (b) 2 Exempel 1:Lösning Illustration av lösning Kod där värdet i variabel a och b byter värde. void main (void){ int a, b, tmp; // deklaration av värde a=10; // a tilldelas värde b=; // b tilldelas värde tmp=a; //kod för att a och b a=b; //byter värde b=tmp; a=10; b=; 0 (a) 10 1 (b) 2 (tmp) tmp=a; a=b; b=tmp; 0 (a) 10 0 (a) 0 (a) 1 (b) 1 (b) 1 (b) 10 2 (tmp) 10 2 (tmp) 10 2 (tmp) 10

Exempel 2:Fråga Skriv en funktion swap som byter värden på två variabler void main (void){ int a, b; // deklaration av värde a = 10; // a tilldelas värde b = ; // b tilldelas värde swap(a,b); Exempel 2:Fråga+problem Skriv en funktion swap som byter värden på två variabler void main (void){ int a, b; // deklaration av värde a = 10; // a tilldelas värde b = ; // b tilldelas värde a=swap(a,b); int swap (int c, d){ int temp; temp=c; c=d; d=temp; return????? Exempel 2: Lösning Skriv en funktion swap som byter värden på två variabler void swap (int *a, *b){ int temp; //vanlig variabel temp=*a; // * ger värdet som a pekar på *a=*b; *b=temp; a=10; b=; Illustration av lösning 0 (a) 1 (b) 2 (tmp) 10 tmp=*a; (tilldelar tmp det som *a pekar på) 0 (a) 1 (b) 2 (tmp) 10 10 *a=*b; (tilldelar det a pekar på värdet som finns i b) 0 (a) 1 (b) 2 (tmp) 10 *b=tmp; (tilldelar den plats b pekar på värdet i tmp) 0 (a) 1 (b) 2 (tmp) 10 10

Variablers synlighet Global variabel Include #include <stdio.h> unsigned char n; void display (unsigned char number){ static int a; int c; c=+a; Global variabel Lokal variabel Includeringsbara bibliotek: #include <stdio.h> standardfunktioner för I/O int main(void){ int b; n=; b=10; display(b); Lokal variabel Dator Inledning Fetch Data/instruktioner Kontroll Central processing unit (CPU) Execute Ett operativsystem (Operating System - OS) är ett program som exekveras på datorn Mål för OS är: Hantera hårdvaruresurser i datorsystemet Erhålla tjänster för exekvering av applikationsprogram (t ex Facebook) I stort sett alla system har någon from av OS från mobiltelefoner, datorspel, till superdatorer.

Unix Linux Linux Linus Benedict Torvalds, född 199, Finland Ville lära sig om OS, skrev ett OS Windows MS-DOS (Microsoft Disk Operating System) (~1980) Windows 1.0, Windows 9, 98, 2000, XP, Vista, 7, 8 Bill Gates Paul Allen Vad gör ett OS? Program Processhantering (Process management) Avbrott (Interrupts) Minneshantering (Memory management) Filsystem (File system) Drivrutiner (Device drivers) Nätverk (Networking) Säkerhet (Security) In och utmatning (I/O) Fetch Execute Fetch Execute Fetch Execute Data/instruktioner Kontroll Central processing unit (CPU) Fetch Execute

Program Byt program Program Byt program Byt program Fetch Execute Fetch Execute Fetch Execute Fetch Fetch Execute Fetch Execute Fetch Execute Fetch 0.1 s 0.1 s 0.1 s Data/instruktioner Kontroll Central processing unit (CPU) Data/instruktioner Kontroll Central processing unit (CPU) Fetch Execute Fetch Execute Vad hinner man på 0.1 sekund? Hur går det till att byta program? Antag processor med 1 GHz klockfrekvens 1 GHz = 1 000 000 000 Hz (svängningar per sekund) På 1 sekund hinner man 1 000 000 000 klockcykler På 0.1 sekund hinner man 100 000 000 klockcykler Om varje instruktion tar 10 klockcykler, hinner man: 10 000 000 instruktioner Fetch Data/instruktioner Kontroll Execute Interrupt enable? Yes! No! Central processing unit (CPU) Interrupt handling

Hur går det till att byta program? Kontextbyte (context switch) 1 0.1 s Process A Process B A running Main OS Data/instruktioner Kontroll Central processing unit (CPU) T I D Save state of A into PCBA Load state of B from PCBB Context switch B running Fetch Execute 2 Kontrollera och hantera avbrott (ändra PC) Save state of B into PCBB Load state of A from PCBA Context switch A running Processkontrollblock Processhantering Process Control Block (PCB, eller Task Controlling Block eller Task Struct) är en datastruktur som innehåller den information som behövs för att kunna hantera en given process. Ett aktivt program har ett processkontrollblock Typiskt innehåll: Identifikation av process (a process identifier, or PID) Register värden, programräknare, stackpekare Adressrymd, prioritet, process information, t ex när användes processen senast, I/O som används, öppna filer

Process modell Processhantering New admitted Ready preemption Running Ett program behöver resurser för att kunna exekvera Ett altenerar mellan CPU och I/O cykler För att maximera utnyttjandet av CPU, används multiprogramming (time sharing, multi-tasking) mer än ett program är aktivt. I/O, event completion dispatch Waiting I/O, wait exit Terminated Fetch Execute Fetch Execute Fetch Execute Fetch Tid för Facebook Tid för Musik 0101 0101 0011 0101 0101 0011 Byt program Data/instruktioner Control Central processing unit (CPU) Processhantering Processmodell En processor flera program som exekverar..eller gör de? Nej! Men, en processor är väldigt snabb, så vi kan ge sken av parallellism. Antag att två program, t ex och körs ~0.1 sekund på varje program, dvs 100 000 000 klockcykler på varje program Fetch Execute Fetch Execute Fetch Execute 0.1 s 0.1 s 0.1 s ~10 olika program kan exekveras per sekund Fetch Två-tillståndsmodell (Running och Not Running) Schemaläggaren väljer en ny process från Not Running kön och låter den exekvera. Ett avbrott (till exempel, vid slut av time slice), leder till context switch och ett nytt program laddas Tre-tillståndsmodell (Running, Ready, Blocked) En nackdel med två tillstånd är att CPUn står idle vid I/O. Ett nytt tillstånd (Blocked) införs). Fem-tillståndsmodell (Running, Ready, Blocked, Ready suspended, Blocked suspended) För hantering av virtuellt minne (flytta en process från primärminnet till sekundärminnet)

Schemaläggare Schemaläggare Långtidsschemaläggaren (Long-term scheduler) Bestämmer vilka jobb som ska läggas i readykön (queue) Mellantidsschemaläggaren (Mid-term scheduler) Bestämmer vilka jobb som ska vara i primärminnet (main) och vilka som ska vara i sekundärminnet Korttidsschemaläggaren (Short-term scheduler) Bestämmer vilket jobb som ska exekvera Algoritmer: First In First Out, Shortest Job First, Priority based scheduling, Round-robin scheduling, Multilevel Queue scheduling MS-DOS non multi-task system; hence, no scheduler Windows.1 - non-preemptive scheduler (did not interrupt programs) Windows NT, Linux, MacOS - multilevel feedback queue Minneshantering Hantera hårdvaruresurser? Vid multiprogrammering kommer flera olika program finnas i primärminnet. Kostar för mycket tid att flytta program till hårddisk vid kontext byte. T ex, två program ska exekveras samtidigt : 0101 0101 0011 0101 0101 0011 Ringar (Rings) är hårdvarustöd för att ge skydd Typiskt med två moder user-mode and supervisor-mode Applikationsprogram gör systemanrop för att läsa på hårddisk (ger OS kontroll) MS-DOS endast supervisor-mode Windows, Linux supervisor och user mode

Systemanrop Polling/avbrott Exempel: Byte av program (process) Avbrott genererat av klocka (time slice) Avbrottsrutin (OS) Huvudprogram (main) Huvudprogram (main) Polling kontinuerlig avläsning av ingång, t ex tangent Processorn slösar bort kraft på att kolla ingång Avbrott ingång genererar avbrott Processorn gör annat fram tills avbrott inträffar Exempel C instruktionen: printf Mjukvaruavbrott genererat av printf (systemanrop) Avbrottsrutin (OS) Huvudprogram (main) Huvudprogram (main) Tid Huvudprogram (main) Avbrott Avbrottsrutin Huvudprogram (main) Tid Tid Minneshantering Filsystem Relocation Flytta program och placera dem på andra ställen i minnet. Kunna hantera minnesreferenser och adresser vid omflyttningar. Minneskydd (Memory protection) Processer ska inte kunna komma åt minnesarea som tilldelats andra processer utan lov Delning (Sharing) Ibland ska processer kunna dela information och därför komma åt samma delar av minnet Hur hålla ordning på alla bitar? Vanligtvis kan man inte adressera individuella bitar (för stor overhead). Filer och bibliotek (Files and directories) Exampel: File Allocation Table (FAT), New Technology File System (NTFS) Mål: Kunna lagra stora filer, nå data snabbt (utnyttja hårddisk maximalt)

Filsystem - Inode Filsystem - Inode Varje fil i Unix har en Inode Example: 12 pekare som pekar direkt på block med filens data (direct pointers) 1 indirekt pekare (en pekare till ett block av pekare) 1 dubbel indirekt pekare (en pekare som pekar på ett block av pekare som i sin tur pekar på ett block av pekare som perkar på filens data) 1 trippel indirekt pekare (som dubble indirekt pekare men med ytterligare en nivå) Vad gör ett OS? Processhantering (Process management) Minneshantering (Memory management) Filsystem (File system) Drivrutiner (Device drivers) Nätverk (Networking) Säkerhet (Security) In och utmatning (I/O)