diff --git a/20230523/io-ports-and-interrupts.pdf b/20230523/io-ports-and-interrupts.pdf new file mode 120000 index 0000000000000000000000000000000000000000..bcd46f7afb35605b20bdb05637e6de0a039893ec --- /dev/null +++ b/20230523/io-ports-and-interrupts.pdf @@ -0,0 +1 @@ +../common/io-ports-and-interrupts.pdf \ No newline at end of file diff --git a/20230523/logo-hochschule-bochum-cvh-text-v2.pdf b/20230523/logo-hochschule-bochum-cvh-text-v2.pdf new file mode 120000 index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8 --- /dev/null +++ b/20230523/logo-hochschule-bochum-cvh-text-v2.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum-cvh-text-v2.pdf \ No newline at end of file diff --git a/20230523/logo-hochschule-bochum.pdf b/20230523/logo-hochschule-bochum.pdf new file mode 120000 index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1 --- /dev/null +++ b/20230523/logo-hochschule-bochum.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum.pdf \ No newline at end of file diff --git a/20230523/parameters-01.c b/20230523/parameters-01.c new file mode 100644 index 0000000000000000000000000000000000000000..ad24b30ad00fef6b885a66cb1d741cc4a63b8c5f --- /dev/null +++ b/20230523/parameters-01.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +typedef char string[42]; + +void print (string msg) +{ + printf ("%s\n", msg); +} + +int main (void) +{ + string hello = "Hello, world!"; + print (hello); + return 0; +} diff --git a/20230523/parameters-01.s b/20230523/parameters-01.s new file mode 100644 index 0000000000000000000000000000000000000000..49a0a7b953b87ff023534e547a56ddfa3929ac25 --- /dev/null +++ b/20230523/parameters-01.s @@ -0,0 +1,42 @@ + .file "parameters-01.c" + .text + .globl print + .type print, @function +print: +.LFB11: + .cfi_startproc + subq $8, %rsp + .cfi_def_cfa_offset 16 + call puts@PLT + addq $8, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE11: + .size print, .-print + .globl main + .type main, @function +main: +.LFB12: + .cfi_startproc + subq $56, %rsp + .cfi_def_cfa_offset 64 + movabsq $8583909746840200520, %rax + movabsq $143418749551, %rdx + movq %rax, (%rsp) + movq %rdx, 8(%rsp) + movq $0, 16(%rsp) + movq $0, 24(%rsp) + movq $0, 32(%rsp) + movw $0, 40(%rsp) + movq %rsp, %rdi + call puts@PLT + movl $0, %eax + addq $56, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE12: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/parameters-02.c b/20230523/parameters-02.c new file mode 100644 index 0000000000000000000000000000000000000000..f87bf3003611179597b504371d65399c8087a181 --- /dev/null +++ b/20230523/parameters-02.c @@ -0,0 +1,8 @@ +#include "paramlib-02.h" + +int main (void) +{ + string hello = "Hello, world!"; + print (hello); + return 0; +} diff --git a/20230523/parameters-02.s b/20230523/parameters-02.s new file mode 100644 index 0000000000000000000000000000000000000000..02bc062d1b91497efb22c4c2d4cc9ac6c16602ba --- /dev/null +++ b/20230523/parameters-02.s @@ -0,0 +1,28 @@ + .file "parameters-02.c" + .text + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + subq $56, %rsp + .cfi_def_cfa_offset 64 + movabsq $8583909746840200520, %rax + movabsq $143418749551, %rdx + movq %rax, (%rsp) + movq %rdx, 8(%rsp) + movq $0, 16(%rsp) + movq $0, 24(%rsp) + movq $0, 32(%rsp) + movw $0, 40(%rsp) + movq %rsp, %rdi + call print@PLT + movl $0, %eax + addq $56, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE0: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/parameters-03.c b/20230523/parameters-03.c new file mode 100644 index 0000000000000000000000000000000000000000..c3570ccb0fa835ec295cba0b7f2e29baf0a91d02 --- /dev/null +++ b/20230523/parameters-03.c @@ -0,0 +1,7 @@ +#include "paramlib-03.h" + +int main (void) +{ + print ('H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\n'); + return 0; +} diff --git a/20230523/parameters-03.s b/20230523/parameters-03.s new file mode 100644 index 0000000000000000000000000000000000000000..14c10b03061cb7210177f3bce08507d051b4933b --- /dev/null +++ b/20230523/parameters-03.s @@ -0,0 +1,41 @@ + .file "parameters-03.c" + .text + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + subq $8, %rsp + .cfi_def_cfa_offset 16 + pushq $10 + .cfi_def_cfa_offset 24 + pushq $33 + .cfi_def_cfa_offset 32 + pushq $100 + .cfi_def_cfa_offset 40 + pushq $108 + .cfi_def_cfa_offset 48 + pushq $114 + .cfi_def_cfa_offset 56 + pushq $111 + .cfi_def_cfa_offset 64 + pushq $119 + .cfi_def_cfa_offset 72 + pushq $32 + .cfi_def_cfa_offset 80 + movl $44, %r9d + movl $111, %r8d + movl $108, %ecx + movl $108, %edx + movl $101, %esi + movl $72, %edi + call print@PLT + movl $0, %eax + addq $72, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE0: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/parameters-03.s-m32 b/20230523/parameters-03.s-m32 new file mode 100644 index 0000000000000000000000000000000000000000..716903dcc1f3031ab704185e525015b369c63ba6 --- /dev/null +++ b/20230523/parameters-03.s-m32 @@ -0,0 +1,65 @@ + .file "parameters-03.c" + .text + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + leal 4(%esp), %ecx + .cfi_def_cfa 1, 0 + andl $-16, %esp + pushl -4(%ecx) + pushl %ebp + .cfi_escape 0x10,0x5,0x2,0x75,0 + movl %esp, %ebp + pushl %ebx + pushl %ecx + .cfi_escape 0xf,0x3,0x75,0x78,0x6 + .cfi_escape 0x10,0x3,0x2,0x75,0x7c + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + subl $8, %esp + pushl $10 + pushl $33 + pushl $100 + pushl $108 + pushl $114 + pushl $111 + pushl $119 + pushl $32 + pushl $44 + pushl $111 + pushl $108 + pushl $108 + pushl $101 + pushl $72 + call print@PLT + addl $64, %esp + movl $0, %eax + leal -8(%ebp), %esp + popl %ecx + .cfi_restore 1 + .cfi_def_cfa 1, 0 + popl %ebx + .cfi_restore 3 + popl %ebp + .cfi_restore 5 + leal -4(%ecx), %esp + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size main, .-main + .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat + .globl __x86.get_pc_thunk.bx + .hidden __x86.get_pc_thunk.bx + .type __x86.get_pc_thunk.bx, @function +__x86.get_pc_thunk.bx: +.LFB1: + .cfi_startproc + movl (%esp), %ebx + ret + .cfi_endproc +.LFE1: + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/parameters-04.c b/20230523/parameters-04.c new file mode 100644 index 0000000000000000000000000000000000000000..937cc4f27242200b55639a1022412331df177bc8 --- /dev/null +++ b/20230523/parameters-04.c @@ -0,0 +1,7 @@ +#include "paramlib-04.h" + +int main (void) +{ + print ("Hä?", 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\n'); + return 0; +} diff --git a/20230523/paramlib-02.c b/20230523/paramlib-02.c new file mode 100644 index 0000000000000000000000000000000000000000..8b13246337b3904c887e40dcddbe98c8d694913f --- /dev/null +++ b/20230523/paramlib-02.c @@ -0,0 +1,7 @@ +#include <stdio.h> +#include "paramlib-02.h" + +void print (string msg) +{ + printf ("%s\n", msg); +} diff --git a/20230523/paramlib-02.h b/20230523/paramlib-02.h new file mode 100644 index 0000000000000000000000000000000000000000..fcfab1f0268fa03a2aa16b67bf6bf320c476723a --- /dev/null +++ b/20230523/paramlib-02.h @@ -0,0 +1,3 @@ +typedef char string[42]; + +extern void print (string msg); diff --git a/20230523/paramlib-03.c b/20230523/paramlib-03.c new file mode 100644 index 0000000000000000000000000000000000000000..96afc514c0f146bab217f5fa5d3214918799c1c3 --- /dev/null +++ b/20230523/paramlib-03.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +void print (int h, int e, int l1, int l2, int o1, + int comma, int space, + int w, int o2, int r, int l3, int d, + int bang, int newline) +{ + printf ("%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + h, e, l1, l2, o1, comma, space, w, o2, r, l3, d, bang, newline); +} diff --git a/20230523/paramlib-03.h b/20230523/paramlib-03.h new file mode 100644 index 0000000000000000000000000000000000000000..c4eaee982ec8be819bdd69aa0993434e98a600fb --- /dev/null +++ b/20230523/paramlib-03.h @@ -0,0 +1,4 @@ +extern void print (int h, int e, int l1, int l2, int o1, + int comma, int space, + int w, int o2, int r, int l3, int d, + int bang, int newline); diff --git a/20230523/paramlib-03.s b/20230523/paramlib-03.s new file mode 100644 index 0000000000000000000000000000000000000000..55c50fee4fe18a8a5ed569f6390a491922099cfa --- /dev/null +++ b/20230523/paramlib-03.s @@ -0,0 +1,55 @@ + .file "paramlib-03.c" + .text + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "%c%c%c%c%c%c%c%c%c%c%c%c%c%c" + .text + .globl print + .type print, @function +print: +.LFB11: + .cfi_startproc + subq $16, %rsp + .cfi_def_cfa_offset 24 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 32 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 40 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 48 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 56 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 64 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 72 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 80 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 88 + pushq %r9 + .cfi_def_cfa_offset 96 + movl %r8d, %r9d + movl %ecx, %r8d + movl %edx, %ecx + movl %esi, %edx + movl %edi, %esi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + addq $88, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE11: + .size print, .-print + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/paramlib-03.s-m32 b/20230523/paramlib-03.s-m32 new file mode 100644 index 0000000000000000000000000000000000000000..7d5b641c66009aa6851c6f7cf4bc5768a7091028 --- /dev/null +++ b/20230523/paramlib-03.s-m32 @@ -0,0 +1,72 @@ + .file "paramlib-03.c" + .text + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "%c%c%c%c%c%c%c%c%c%c%c%c%c%c" + .text + .globl print + .type print, @function +print: +.LFB11: + .cfi_startproc + pushl %ebx + .cfi_def_cfa_offset 8 + .cfi_offset 3, -8 + subl $12, %esp + .cfi_def_cfa_offset 20 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + pushl 72(%esp) + .cfi_def_cfa_offset 24 + pushl 72(%esp) + .cfi_def_cfa_offset 28 + pushl 72(%esp) + .cfi_def_cfa_offset 32 + pushl 72(%esp) + .cfi_def_cfa_offset 36 + pushl 72(%esp) + .cfi_def_cfa_offset 40 + pushl 72(%esp) + .cfi_def_cfa_offset 44 + pushl 72(%esp) + .cfi_def_cfa_offset 48 + pushl 72(%esp) + .cfi_def_cfa_offset 52 + pushl 72(%esp) + .cfi_def_cfa_offset 56 + pushl 72(%esp) + .cfi_def_cfa_offset 60 + pushl 72(%esp) + .cfi_def_cfa_offset 64 + pushl 72(%esp) + .cfi_def_cfa_offset 68 + pushl 72(%esp) + .cfi_def_cfa_offset 72 + pushl 72(%esp) + .cfi_def_cfa_offset 76 + leal .LC0@GOTOFF(%ebx), %eax + pushl %eax + .cfi_def_cfa_offset 80 + call printf@PLT + addl $72, %esp + .cfi_def_cfa_offset 8 + popl %ebx + .cfi_restore 3 + .cfi_def_cfa_offset 4 + ret + .cfi_endproc +.LFE11: + .size print, .-print + .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat + .globl __x86.get_pc_thunk.bx + .hidden __x86.get_pc_thunk.bx + .type __x86.get_pc_thunk.bx, @function +__x86.get_pc_thunk.bx: +.LFB12: + .cfi_startproc + movl (%esp), %ebx + ret + .cfi_endproc +.LFE12: + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/paramlib-04.c b/20230523/paramlib-04.c new file mode 100644 index 0000000000000000000000000000000000000000..20b88b0f94e334276896154cb9a2d80a1942b047 --- /dev/null +++ b/20230523/paramlib-04.c @@ -0,0 +1,11 @@ +#include <stdio.h> + +void print (char *Hae, + int h, int e, int l1, int l2, int o1, + int comma, int space, + int w, int o2, int r, int l3, int d, + int bang, int newline) +{ + printf ("%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + h, e, l1, l2, o1, comma, space, w, o2, r, l3, d, bang, newline); +} diff --git a/20230523/paramlib-04.h b/20230523/paramlib-04.h new file mode 100644 index 0000000000000000000000000000000000000000..b86e3216ab7b9fd98ecacd5dc5cc8323d9e923dc --- /dev/null +++ b/20230523/paramlib-04.h @@ -0,0 +1,5 @@ +extern void print (char *Hae, + int h, int e, int l1, int l2, int o1, + int comma, int space, + int w, int o2, int r, int l3, int d, + int bang, int newline); diff --git a/20230523/paramlib-04.s b/20230523/paramlib-04.s new file mode 100644 index 0000000000000000000000000000000000000000..c3ce0464d86b85dd905a74706f63b6bb3c538c70 --- /dev/null +++ b/20230523/paramlib-04.s @@ -0,0 +1,51 @@ + .file "paramlib-04.c" + .text + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "%c%c%c%c%c%c%c%c%c%c%c%c%c%c" + .text + .globl print + .type print, @function +print: +.LFB11: + .cfi_startproc + subq $16, %rsp + .cfi_def_cfa_offset 24 + movl 88(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 32 + movl 88(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 40 + movl 88(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 48 + movl 88(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 56 + movl 88(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 64 + movl 88(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 72 + movl 88(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 80 + movl 88(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 88 + movl 88(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 96 + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + addq $88, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE11: + .size print, .-print + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/pgslides.sty b/20230523/pgslides.sty new file mode 120000 index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64 --- /dev/null +++ b/20230523/pgslides.sty @@ -0,0 +1 @@ +../common/pgslides.sty \ No newline at end of file diff --git a/20230523/rtech-20230523.pdf b/20230523/rtech-20230523.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f95e0223aa56b6d123607969dbe8c9aaddbc8bad Binary files /dev/null and b/20230523/rtech-20230523.pdf differ diff --git a/20230523/rtech-20230523.tex b/20230523/rtech-20230523.tex new file mode 100644 index 0000000000000000000000000000000000000000..950b48c83a51e7803b24ae69afc795d8b8d7dfb3 --- /dev/null +++ b/20230523/rtech-20230523.tex @@ -0,0 +1,1743 @@ +% rtech-20230523.pdf - Lecture Slides on Computer Technology +% Copyright (C) 2012, 2013, 2014, 2021, 2022, 2023 Peter Gerwinski +% +% This document is free software: you can redistribute it and/or +% modify it either under the terms of the Creative Commons +% Attribution-ShareAlike 3.0 License, or under the terms of the +% GNU General Public License as published by the Free Software +% Foundation, either version 3 of the License, or (at your option) +% any later version. +% +% This document is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this document. If not, see <http://www.gnu.org/licenses/>. +% +% You should have received a copy of the Creative Commons +% Attribution-ShareAlike 3.0 Unported License along with this +% document. If not, see <http://creativecommons.org/licenses/>. + +% README: Der CPU-Stack + +\documentclass[10pt,t]{beamer} + +\usepackage{pgslides} +\usepackage{pdftricks} +%\usepackage[obeyfamily=false,mathrm=mathsf,textrm=sffamily]{siunitx} +%\usepackage{eurosym} +\usepackage{tikz} + +\newcommand{\Cin}{C\raisebox{-0.5ex}{\footnotesize in}} +\newcommand{\Cout}{C\raisebox{-0.5ex}{\footnotesize out}} + +\lstdefinestyle{asm}{basicstyle=\color{structure}, + language={}, + gobble=4} + +\begin{psinputs} + \usepackage[utf8]{inputenc} + \usepackage[german]{babel} + \usepackage[T1]{fontenc} + \usepackage{helvet} + \renewcommand*\familydefault{\sfdefault} + \usepackage{pstricks,pst-grad,pst-circ-pg} + \newcommand{\invisible}{\tiny\color{white}} + \psset{unit=1cm} + \psset{logicLabelstyle=\invisible} + \newcommand{\logicSymbol}{\small\boldmath\bf\rule{0pt}{0.5cm}} + \psset{logicSymbolstyle=\logicSymbol} + \newcommand{\Cin}{C\raisebox{-0.5ex}{\footnotesize in}} + \newcommand{\Cout}{C\raisebox{-0.5ex}{\footnotesize out}} +\end{psinputs} + +\title{Rechnertechnik} +\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski} +\date{23.\ Mai 2022} + +\begin{document} + +\maketitleframe + +\nosectionnonumber{\inserttitle} + +\begin{frame} + + \shownosectionnonumber + + \begin{itemize} + \item[\textbf{1}] \textbf{Einführung} + \item[\textbf{2}] \textbf{Vom Schaltkreis zum Computer} + \item[\textbf{3}] \textbf{Assember-Programmierung} + \begin{itemize} + \item[3.1] Struktur von Assembler-Programmen + \item[3.2] Beispiel: Redcode + \color{medgreen} + \item[3.3] Architekturmerkmale von Prozessore + \color{orange} + \item[3.4] Der CPU-Stack + \color{red} + \item[3.5] Computer-Sprachen + \end{itemize} +% \color{gray} +% \item[\textbf{5}] \textbf{Hardwarenahe Programmierung} +% \item[\textbf{6}] \textbf{Anwender-Software} +% \item[\textbf{7}] \textbf{Bus-Systeme} +% \item[\textbf{8}] \textbf{Pipelining} +% \item[\textbf{9}] \textbf{Ausblick} + \item[\textbf{\dots\hspace{-0.75em}}] + \end{itemize} + +\end{frame} + +\setcounter{section}{2} +\section{Assembler-Programmierung} +\setcounter{subsection}{2} +\subsection{Architekturmerkmale von Prozessoren} +\subsubsection{Speicherarchitekturen} + +\begin{frame} + + \showsubsection + + Oder: Jede Assembler-Sprache ist anders. + + \bigskip + + \showsubsubsection + + Bezeichnungen + \begin{itemize} + \item + \newterm{Bit\/} = 0 oder 1 -- kleinste Einheit an Information + \item + \newterm{Byte\/} = Zusammenfassung mehrerer \newterm{Bits}\\ + zu einer Binärzahl, die ein Zeichen (\newterm{Character\/}) darstellen kann,\\ + häufig 8 Bits (\newterm{Oktett\/}) + \item + \newterm{Speicherwort\/} = Zusammenfassung mehrerer Bits\\ + zu der kleinsten adressierbaren Einheit, häufig 1 Byte + \item + \newterm{RAM\/} = \newterm{Random Access Memory\/} = Hauptspeicher + \item + \newterm{ROM\/} = \newterm{Read Only Memory\/} = nur lesbarer Speicher + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsubsection + + Verschiedene Arten von Speicher + \begin{itemize} + \item + \newterm{Prozessor-Register}\\ + können direkt mit ALU verbunden werden,\\ + besonders schnell (Flipflops),\\ + überschaubare Anzahl von Registern + \item + \newterm{Hauptspeicher}\\ + kann direkt adressiert und mit Prozessor-Registern abgeglichen werden,\\ + heute i.\,d.\,R.\ dynamischer Speicher (Kondensatoren) + \item + \newterm{I/O-Ports}\\ + sind spezielle Speicheradressen, über die\\ + mit externen Geräten kommuniziert wird + \item + \newterm{Massenspeicher}\\ + liegt auf externem Gerät, wird über I/O-Ports angesprochen,\\ + Festplatte, Flash-Speicher, \dots + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsubsubsection + + \begin{itemize} + \item + \newterm{Von-Neumann-Architektur}\\ + Es gibt nur 1 Hauptspeicher, in dem sich sowohl die Befehle\\ + als auch die Daten befinden. + + \begin{onlyenv}<1> + \smallskip + + Vorteil: Flexibilität in der Speichernutzung + + Nachteil: Befehle können überschrieben werden.\\ + $\longrightarrow$ Abstürze und Malware möglich + \end{onlyenv} + + \pause + \item + \newterm{Harvard-Architektur}\\ + Es gibt 2 Hauptspeicher. In einem befinden sich die Befehle,\\ + im anderen die Daten. + + \begin{onlyenv}<2> + \smallskip + + Vorteil: Befehle können nicht überschrieben werden\\ + $\longrightarrow$ sicherer als Von-Neumann-Architektur + + Nachteile: Leitungen zum Speicher (Bus) müssen doppelt vorhanden sein,\\ + freier Befehlsspeicher kann nicht für Daten genutzt werden. + \end{onlyenv} + + \pause + \item + Weitere Kombinationen\\ + Hauptspeicher und I/O-Ports gemeinsam oder getrennt,\\ + Hauptspeicher und Prozessorregister gemeinsam oder getrennt + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsubsubsection + + Beispiele: + \begin{itemize} + \item + Intel IA-32, AMD64:\\ + Von-Neumann-Architektur (plus Speicherschutzmechanismen),\\ + Prozessorregister und I/O-Ports vom Hauptspeicher getrennt + \item + Atmel AVR (z.\,B.\ ATmega):\\ + Harvard-Architektur\\ + (Befehlsspeicher als Flash-Speicher grundsätzlich auch schreibbar),\\ + Prozessorregister und I/O-Ports in gemeinsamem Adressbereich mit Hauptspeicher + \item + 6502, Renesas 740-CPU, Renesas-38000-Mikrocontroller:\\ + Von-Neumann-Architektur,\\ + I/O-Ports in gemeinsamem Adressbereich mit Hauptspeicher,\\ + Prozessorregister und Hauptspeicher getrennt + \end{itemize} + +\end{frame} + +\subsubsection{Registerarchitekturen} + +\begin{frame}[fragile] + + \showsubsubsection + + \vspace*{-\medskipamount} + + \begin{itemize} + \item + Mehrere Register, einzeln ansprechbar + \item + \newterm{Akkumulator\/}: Nur 1 Register kann rechnen. + \item + \newterm{Stack-Architektur\/}: Stapel, "`umgekehrte Polnische Notation"' + \end{itemize} + + \pause + + Operationen: typischerweise nur + \lstinline{=}, \lstinline{+=}, \lstinline{-=}, \lstinline{*=}, \lstinline{/=}, \dots + + \pause + \medskip + + Beispiel: \lstinline{c = a + 2 * b;} + + \pause + \medskip + + \begin{minipage}[t]{2cm} + C, Java:\smallskip\par + \begin{lstlisting}[gobble=6] + R = b; + R *= 2; + R += a; + c = R; + \end{lstlisting} + \end{minipage}\pause + \begin{minipage}[t]{4cm} + Mehrere Register:\smallskip\par + \begin{lstlisting}[style=asm,gobble=6] + movl (b), %eax + imull $2, %eax, %eax + addl (a), %eax + movl %eax, (c) + \end{lstlisting} + \smallskip\par + (IA-32-Assembler) + \end{minipage}\pause + \begin{minipage}[t]{3cm} + Akkumulator:\smallskip\par + \begin{lstlisting}[style=asm,gobble=6] + load (b) + mul $2 + add (a) + store (c) + \end{lstlisting} + \smallskip\par + (Pseudo-Assembler) + \end{minipage}\pause + \begin{minipage}[t]{3cm} + Register-Stack:\smallskip\par + \begin{lstlisting}[style=asm,gobble=6] + push (a) + push (b) + push $2 + mul + add + pop (c) + \end{lstlisting} + \end{minipage} + +\end{frame} + +\begin{frame} + + \showsubsubsection + + Beispiele: + \begin{itemize} + \item + Intel IA-32, AMD64:\\ + Mehrere Register, für verschiedene Zwecke spezialisiert (unübersichtlich),\\[\smallskipamount] + Fließkommaregister: Stack-Architektur + \item + Atmel AVR (z.\,B.\ ATmega):\\ + 32 Register + \item + 6502, Renesas 740-CPU, Renesas-38000-Mikrocontroller:\\ + 3 Register: A, X, Y. Nur A kann rechnen $\longrightarrow$ Akkumulator + \item + Java Virtual Machine (JVM):\\ + Stack-Architektur + \item + Redcode:\\ + Jede Speicherzelle fungiert als Register + \end{itemize} + +\end{frame} + +\subsubsection{Befehlssätze} + +\begin{frame} + + \showsubsubsection + + \begin{itemize} + \item + \newterm{Reduced Instruction Set Computer (RISC)} + + \smallskip + + wenige, wenig mächtige Befehle + + \begin{onlyenv}<1> + \textarrow\ Programmierung in Assembler für Menschen unkomfortabel\\ + \textarrow\ schnelle Abarbeitung der Befehle + + \medskip + + Beispiel: Atmel AVR + \begin{itemize} + \item + Der ``load immediate''-Befehl funktioniert nur + für die Register 16 bis 31,\\ + nicht für die Register 0 bis 15. + \item + Die meisten Befehle werden in nur 1 Taktzyklus abgearbeitet. + \end{itemize} + + \medskip + + Beispiel: Redcode ICWS-86 + \begin{itemize} + \item + Es gibt indirekte Adressierung mit Prä-Dekrement,\\ + aber nicht mit Prä-Inkrement. + \item + Alle Befehle werden in nur 1 Taktzyklus abgearbeitet. + \end{itemize} + \end{onlyenv} + + \pause + \medskip + \item + \newterm{Complex Instruction Set Computer (CISC)} + + \smallskip + + Umfangreiche Befehlssätze, mächtige Befehle + + \begin{onlyenv}<2> + \textarrow\ komfortable manuelle Programmierung in Assembler\\ + \textarrow\ längere Abarbeitungszeit der einzelnen Befehle + + \smallskip + + Realisierung: "`Prozessor im Prozessor"' -- \newterm{Mikroprogramme} + + \medskip + + Beispiel: Intel IA-32, AMD64 + \begin{itemize} + \item + Es gibt spezielle Befehle für BCD- und String-Operationen. + \item + Befehle benötigen meistens 2 oder mehr,\\ + gelegentlich (z.\,B.\ Fließkomma-Operationen) auch über 100 Taktzyklen. + \end{itemize} + \end{onlyenv} + + \medskip + \pause + \item + \newterm{Very Long Instruction Word (VLIW)\/} und\\ + \newterm{Explicitly Parallel Instruction Computing (EPIC)} + + \smallskip + + mehrere Befehle gleichzeitig ausführbar + + \begin{onlyenv}<3> + \textarrow\ mehr Rechenleistung möglich\\ + \textarrow\ Programmierung sehr aufwendig + + \medskip + + Beispiel: Intel IA-64 + \end{onlyenv} + + \pause + \medskip + \item + \newterm{Orthogonaler Befehlssatz} + + \smallskip + + Jeder Befehl ist mit jeder Adressierungsart kombinierbar. + + \medskip + + Beispiel: Redcode + \end{itemize} + \vspace*{-4cm} + +\end{frame} + +\subsection{Der CPU-Stack\label{CPU-Stack}} +\addtocounter{subsubsection}{-1} +\subsubsection{Was ist ein Stack?} + +\begin{frame}[fragile] + + \showsubsection + \showsubsubsection + + \bigskip + +\iffalse + + \begin{minipage}[b]{6cm} + \begin{center} + "`First In -- First Out"' + + \bigskip + + \begin{picture}(6,4) + \thicklines + \color{structure} + \put(0.5,0){\line(1,0){5}} + + \put(3.5,0){\only<1-5>{\line(0,1){1}}} + \put(4.5,0){\only<1-4>{\line(0,1){1}}} + \put(3.5,1){\only<1-4>{\line(1,0){1}}} + \put(4.0,0.5){\only<1-4>{\makebox(0,0){\lstinline{3}}}} + \put(3.0,1.5){\only<1>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(3.0,1.5){\only<1>{\makebox(0,0)[b]{\lstinline{push (3)}}}} + + \put(2.5,0){\only<2-6>{\line(0,1){1}}} + \put(2.5,1){\only<2-5>{\line(1,0){1}}} + \put(3.0,0.5){\only<2-5>{\makebox(0,0){\lstinline{7}}}} + \put(2.0,1.5){\only<2>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(2.0,1.5){\only<2>{\makebox(0,0)[b]{\lstinline{push (7)}}}} + + \put(1.5,0){\only<3-6>{\line(0,1){1}}} + \put(1.5,1){\only<3-6>{\line(1,0){1}}} + \put(2.0,0.5){\only<3-6>{\makebox(0,0){\lstinline{137}}}} + \put(1.0,1.5){\only<3>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(1.0,1.5){\only<3>{\makebox(0,0)[b]{\lstinline{push (137)}}}} + + \put(4.55,1.05){\only<4>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(5.00,1.60){\only<4>{\makebox(0,0)[b]{\lstinline{pop ()}: 3}}} + + \put(3.55,1.05){\only<5>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(4.00,1.60){\only<5>{\makebox(0,0)[b]{\lstinline{pop ()}: 7}}} + + \put(2.55,1.05){\only<6>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(3.00,1.60){\only<6>{\makebox(0,0)[b]{\lstinline{pop ()}: 137}}} + \end{picture} + + \bigskip + + FIFO = Queue = Reihe + \end{center} + \end{minipage}\hfill + +\fi + + \begin{minipage}[b]{6cm} + \begin{center} + "`Last In -- First Out"' + + \bigskip + + \begin{picture}(6,4) + \thicklines + \color{structure} + \put(1.5,0){\line(1,0){3}} + + \put(2.5,0){\line(0,1){1}} + \put(3.5,0){\line(0,1){1}} + \put(2.5,1){\line(1,0){1}} + \put(3.0,0.5){\makebox(0,0){\lstinline{3}}} + \put(2.0,1.5){\only<1>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(2.0,1.5){\only<1>{\makebox(0,0)[b]{\lstinline{push (3)}}}} + + \put(2.5,1){\only<2-5>{\line(0,1){1}}} + \put(3.5,1){\only<2-5>{\line(0,1){1}}} + \put(2.5,2){\only<2-5>{\line(1,0){1}}} + \put(3.0,1.5){\only<2-5>{\makebox(0,0){\lstinline{7}}}} + \put(2.0,2.5){\only<2>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(2.0,2.5){\only<2>{\makebox(0,0)[b]{\lstinline{push (7)}}}} + + \put(2.5,2){\only<3-4>{\line(0,1){1}}} + \put(3.5,2){\only<3-4>{\line(0,1){1}}} + \put(2.5,3){\only<3-4>{\line(1,0){1}}} + \put(3.0,2.5){\only<3-4>{\makebox(0,0){\lstinline{137}}}} + \put(2.0,3.5){\only<3>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(2.0,3.5){\only<3>{\makebox(0,0)[b]{\lstinline{push (137)}}}} + + \put(3.55,3.05){\only<4>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(4.00,3.60){\only<4>{\makebox(0,0)[b]{\lstinline{pop ()}: 137}}} + + \put(3.55,2.05){\only<5>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(4.00,2.60){\only<5>{\makebox(0,0)[b]{\lstinline{pop ()}: 7}}} + + \put(3.55,1.05){\only<6>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(4.00,1.60){\only<6>{\makebox(0,0)[b]{\lstinline{pop ()}: 3}}} + \end{picture} + + \bigskip + + LIFO = Stack = Stapel + \end{center} + \end{minipage} + +% +% \dots + +\end{frame} +\subsubsection{Implementierung} + +\begin{frame} + + \showsubsection + \showsubsubsection + + Speicher, in dem Werte "`gestapelt"' werden: \newterm{Stack} + + \begin{itemize} + \item + Speicherbereich (ein array) reservieren + \item + Variable (typischerweise: Prozessorregister) als + \newterm{Stack Pointer\/} reservieren \textarrow\ \lstinline{SP} + \item + Assembler-Befehl \lstinline[style=asm]{push foo}: \quad + \lstinline{*SP++ = foo;} + \begin{itemize} + \item + In der Speicherzelle, + auf die der Stack Pointer \lstinline{SP} gerade zeigt,\\ + den Wert \lstinline{foo} speichern. + \item + Danach den Stack Pointer inkrementieren (um 1 erhöhen). + \end{itemize} + \item + Assembler-Befehl \lstinline[style=asm]{pop bar}: \quad + \lstinline{bar = *--SP;} + \begin{itemize} + \item + Zuerst den Stack Pointer dekrementieren (um 1 erniedrigen). + \item + Danach aus der Speicherzelle,\\ + auf die der Stack Pointer \lstinline{SP} gerade zeigt,\\ + einen Wert lesen und in der Variablen \lstinline{bar} speichern. + \end{itemize} + \end{itemize} + + \pause + \medskip + Speziell: Unterprogramme + +\end{frame} + +\subsubsection{Unterprogramme} + +\begin{frame}[fragile] + + \showsubsection + \showsubsubsection + + \begin{minipage}[t]{4.5cm} + Parameter: + \begin{itemize} + \item + Prozessorregister + \item + CPU-Stack + \end{itemize} + + \smallskip + + Rückgabewert: + \begin{itemize} + \item + Prozessorregister + \end{itemize} + \end{minipage}% + \begin{minipage}[t]{5cm} + Aufruf: + \begin{itemize} + \item + \lstinline[style=asm]{push IP}\\ + \lstinline[style=asm]{jmp foo} + {\color{red}\boldmath $\longleftarrow$ mov \#foo IP}\\ + \textarrow\ \lstinline[style=asm]{call foo} + \end{itemize} + Rücksprung: + \begin{itemize} + \item + \lstinline[style=asm]{pop IP}\\ + \textarrow\ \lstinline[style=asm]{ret} + \end{itemize} + \end{minipage} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + \showsubsubsection + + \begin{minipage}[t]{4.5cm} + Parameter: + \begin{itemize} + \item + Prozessorregister + \item + CPU-Stack + \end{itemize} + + \smallskip + + Rückgabewert: + \begin{itemize} + \item + Prozessorregister + \end{itemize} + \end{minipage}% + \begin{minipage}[t]{5cm} + Aufruf: + \begin{itemize} + \item + \lstinline[style=asm]{push IP}\\ + \lstinline[style=asm]{jmp foo} + {\color{red}\boldmath $\longleftarrow$ mov \#foo IP}\\ + \textarrow\ \lstinline[style=asm]{call foo} + \end{itemize} + Rücksprung: + \begin{itemize} + \item + \lstinline[style=asm]{pop IP}\\ + \textarrow\ \lstinline[style=asm]{ret} + \end{itemize} + \end{minipage} + + \bigskip + + \subsubsection{Lokale Variable} + \showsubsubsection + + \dots\ speichert man oft ebenfalls auf dem Stack. + + \smallskip + + Speicherplatz reservieren: Stack-Pointer modifizieren + + \medskip + + \newterm{Buffer Overflow\/}:\\ + Über die Grenzen einer lokalen Variablen hinausschreiben,\\ + dabei Rücksprungadresse überschreiben \textarrow\ Absturz + +\end{frame} + +\subsubsection{Register sichern} + +\begin{frame} + + \showsubsection + \showsubsubsection + + Ein Unterprogramm verändert Registerinhalte. + \begin{itemize} + \item + im Hauptprogramm nötigenfalls vor Aufruf sichern + \item + im Unterprogramm vor Benutzung sichern + \item + Kombinationen (manche Register so, manche so) + \end{itemize} + +\end{frame} + +\subsection{Computer-Sprachen} +\subsubsection{Maschinensprache} + +\iffalse + +\begin{frame} + + \showsubsection + \showsubsubsection + + \strut\hfill + \begin{minipage}{6.5cm} + \vspace*{-1.7cm} + \small + Computer + \begin{itemize}\itemsep0pt + \item Rechenwerk (ALU) + \item Speicher: Register,\\ + adressierbarer Hauptspeicher + \item Takt: Befehle abarbeiten + \item Peripherie: Kommunikation\\ + mit der Außenwelt + \arrowitem in Maschinensprache programmierbar + \end{itemize} + \end{minipage}\hspace*{-0.5cm} + + In jedem Takt: + \begin{itemize} + \item + dort aus dem Hauptspeicher lesen, wohin das Register \lstinline{IP} zeigt\\ + \textarrow\ \newterm{Befehl\/} (\newterm{Instruction\/} -- \lstinline{IP} = \newterm{Instruction Pointer\/}) + \item + den \newterm{Befehl\/} an den \newterm{Funktion\/}-Eingang der \newterm{ALU\/} legen + \item + auf ähnliche Weise weitere Daten an den \newterm{Akkumulator\/}-\\ + und den \newterm{Daten\/}-Eingang der \newterm{ALU\/} legen + \item + auf ähnliche Weise den \newterm{Ergebnis\/}-Ausgang der \newterm{ALU}\\ + in den Hauptspeicher schreiben + \textarrow\ Befehl ausgeführt + \item + Register \lstinline{IP} hochzählen + \textarrow\ nächster Befehl + \arrowitem + Maschinensprache + \end{itemize} + +\end{frame} + +\fi + +\begin{frame} + + \showsubsection + \showsubsubsection + + \begin{itemize} + \item + Lade- und Speicher-Befehle\\ + arithmetische Befehle\\ + unbedingte und bedingte Sprungbefehle + \arrowitem + Der Computer kann "`alles"' -- \newterm{Turing-Vollständigkeit} + \bigskip + \item + Maschinensprache = Zahlen \textarrow\ für Menschen schwer handhabbar + \arrowitem + Namen für die Befehle: \newterm{Mnemonics} + \arrowitem + \newterm{Assembler\/}-Sprache + \end{itemize} + +\end{frame} + +\subsubsection{\strut{\protect\color{gray}Maschinensprache \protect\textarrow\ }Assembler} + +\begin{frame}[fragile] + + \showsubsubsection + + Beispiel: Intel-x86-16-Bit-Assembler + + \begin{itemize} + \item + Lade- und Speicher-Befehle\hfill + \lstinline{mov}, \dots\\ + arithmetische Befehle\hfill + \lstinline{add}, \lstinline{sub}, \lstinline{inc}, \lstinline{dec}, + \lstinline{xor}, \lstinline{cmp}, \dots\\ + unbedingte und bedingte Sprungbefehle\hfill + \lstinline{jmp}, \lstinline{jz}, \lstinline{jae}, \dots + \item + Register\hfill + \lstinline{ax}, \lstinline{bx}, \dots + \end{itemize} + +% \begin{onlyenv}<1> +% \begin{center} +%% \includegraphics[width=10cm]{programm-screenshot.png} +% \vspace*{-0.5cm} +% \end{center} +% \end{onlyenv} +% \begin{onlyenv}<2-> + + \bigskip + + Beispiel: Atmel-AVR-8-Bit-Assembler + + \begin{itemize} + \item + Lade- und Speicher-Befehle\hfill + \lstinline{ldi}, \lstinline{lds}, \lstinline{sti}, \dots\\ + arithmetische Befehle\hfill + \lstinline{add}, \lstinline{sub}, \lstinline{subi}, + \lstinline{eor}, \lstinline{cp}, \dots\\ + unbedingte und bedingte Sprungbefehle\hfill + \lstinline{rjmp}, \lstinline{brsh}, \lstinline{brlo}, \dots + \item + Register\hfill + \lstinline{r0}, \lstinline{r1}, \dots + \end{itemize} + + \bigskip + + \textarrow\ für jeden Prozessor anders + +% \end{onlyenv} + +\end{frame} + +\subsubsection{\strut{\protect\color{gray}Maschinensprache \protect\textarrow\ Assembler \protect\textarrow\ }Hochsprachen} + +\begin{frame}[fragile] + + \showsubsubsection + + Beispiel: Intel-x86-16-Bit-Assembler + + \begin{itemize} + \item + Lade- und Speicher-Befehle\hfill + \lstinline{mov}, \dots\\ + arithmetische Befehle\hfill + \lstinline{add}, \lstinline{sub}, \lstinline{inc}, \lstinline{dec}, + \lstinline{xor}, \lstinline{cmp}, \dots\\ + unbedingte und bedingte Sprungbefehle\hfill + \lstinline{jmp}, \lstinline{jz}, \lstinline{jae}, \dots + \item + Register\hfill + \lstinline{ax}, \lstinline{bx}, \dots + \end{itemize} + + \bigskip + + Beispiel: Atmel-AVR-8-Bit-Assembler + + \begin{itemize} + \item + Lade- und Speicher-Befehle\hfill + \lstinline{ldi}, \lstinline{lds}, \lstinline{sti}, \dots\\ + arithmetische Befehle\hfill + \lstinline{add}, \lstinline{sub}, \lstinline{subi}, + \lstinline{eor}, \lstinline{cp}, \dots\\ + unbedingte und bedingte Sprungbefehle\hfill + \lstinline{rjmp}, \lstinline{brsh}, \lstinline{brlo}, \dots + \item + Register\hfill + \lstinline{r0}, \lstinline{r1}, \dots + \end{itemize} + + \bigskip + + \textarrow\ für jeden Prozessor anders + + \bigskip + + Hochsprache \textarrow\ für jeden Prozessor gleich + +\end{frame} + +\begin{frame}[fragile] + + \showsubsubsection + + Compiler-Sprachen + \begin{itemize} + \item + \newterm{Compiler\/} übersetzt Hochsprachen-\newterm{Quelltext\/} in die Assembler-Sprache + \item + \newterm{Assembler\/} übersetzt Assembler-Quelltext in die Maschinensprache + \item + Compiler und Assembler sind Programme,\\ + geschrieben in Maschinensprache, Assembler oder einer Hochsprache + \item + Beispiele: Fortran, Algol, Pascal, Ada, C, C++, \dots + \end{itemize} + + \pause + \medskip + Interpreter- oder Skript-Sprachen + \begin{itemize} + \item + \newterm{Interpreter\/} liest Hochsprachen-\newterm{Quelltext\/} und führt ihn sofort aus + \item + Der Interpreter ist ein Programm,\\ + geschrieben in Maschinensprache, Assembler oder einer Hochsprache + \item + Beispiele: Unix-Shell, BASIC, Perl, Python, \dots + \end{itemize} + + \pause + \medskip + Kombinationen + \begin{itemize} + \item + \newterm{Compiler\/} erzeugt \newterm{Zwischencode\/} für eine \newterm{virtuelle Maschine} + \item + \newterm{Interpreter\/} liest Hochsprachen-\newterm{Zwischencode\/} und führt ihn sofort aus + \item + Die virtuelle Maschine ist ein Programm, + geschrieben in Maschinensprache, Assembler, einer Hoch- oder Skript-Sprache + \item + Beispiele: UCSD-Pascal, Java, \dots + \end{itemize} + \medskip + +\end{frame} + +\section{Hardwarenahe Programmierung} +\subsection{Bit-Operationen} +\subsubsection{Zahlensysteme} + +\begin{frame}[fragile] + + \showsection + \vspace*{-\smallskipamount} + \showsubsection + \vspace*{-\medskipamount} + \showsubsubsection + + \begin{tabular}{rlrl} + Basis & Name & Beispiel & Anwendung \\[\smallskipamount] + 2 & Binärsystem & 1\,0000\,0011 & Bit-Operationen \\ + 8 & Oktalsystem & \lstinline,0403, & Dateizugriffsrechte (Unix) \\ + 10 & Dezimalsystem & \lstinline,259, & Alltag \\ + 16 & Hexadezimalsystem & \lstinline,0x103, & Bit-Operationen \\ + 256 & (keiner gebräuchlich) & 0.0.1.3 & IP-Adressen (IPv4) + \end{tabular} + + \bigskip + + \begin{itemize} + \item + Computer rechnen im Binärsystem. + \item + Für viele Anwendungen (z.\,B.\ I/O-Ports, Grafik, \dots) ist es notwendig,\\ + Bits in Zahlen einzeln ansprechen zu können. + \end{itemize} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsubsection + + \begin{tabular}{rlrlrc} + \qquad 000 & \bf 0 \hspace*{1.5cm} & 0000 & \bf 0 & \quad 1000 & \bf 8\\ + 001 & \bf 1 & 0001 & \bf 1 & 1001 & \bf 9\\ + 010 & \bf 2 & 0010 & \bf 2 & 1010 & \bf A\\ + 011 & \bf 3 & 0011 & \bf 3 & 1011 & \bf B\\[\smallskipamount] + 100 & \bf 4 & 0100 & \bf 4 & 1100 & \bf C\\ + 101 & \bf 5 & 0101 & \bf 5 & 1101 & \bf D\\ + 110 & \bf 6 & 0110 & \bf 6 & 1110 & \bf E\\ + 111 & \bf 7 & 0111 & \bf 7 & 1111 & \bf F\\ + \end{tabular} + + \medskip + + \begin{itemize} + \item + Oktal- und Hexadezimalzahlen lassen sich ziffernweise\\ + in Binär-Zahlen umrechnen. + \item + Hexadezimalzahlen sind eine Kurzschreibweise für Binärzahlen,\\ + gruppiert zu jeweils 4 Bits. + \item + Oktalzahlen sind eine Kurzschreibweise für Binärzahlen,\\ + gruppiert zu jeweils 3 Bits. + \item + Trotz Taschenrechner u.\,ä.\ lohnt es sich,\\ + die o.\,a.\ Umrechnungstabelle \textbf{auswendig} zu kennen. + \end{itemize} + +\end{frame} + +\subsubsection{Bit-Operationen in C} + +\begin{frame}[fragile] + + \showsubsubsection + + \begin{tabular}{lll} + C-Operator & Verknüpfung & Anwendung \\[\smallskipamount] + \lstinline,&, & Und & Bits gezielt löschen \\ + \lstinline,|, & Oder & Bits gezielt setzen \\ + \lstinline,^, & Exklusiv-Oder & Bits gezielt invertieren \\ + \lstinline,~, & Nicht & Alle Bits invertieren \\[\smallskipamount] + \lstinline,<<, & Verschiebung nach links & Maske generieren \\ + \lstinline,>>, & Verschiebung nach rechts & Bits isolieren + \end{tabular} + + \bigskip + + Numerierung der Bits: von rechts ab 0 + + \medskip + + \begin{tabular}{ll} + Bit Nr.\ 3 auf 1 setzen: & + \lstinline,a |= 1 << 3;, \\ + Bit Nr.\ 4 auf 0 setzen: & + \lstinline,a &= ~(1 << 4);, \\ + Bit Nr.\ 0 invertieren: & + \lstinline,a ^= 1 << 0;, + \end{tabular} + + \smallskip + + ~~Abfrage, ob Bit Nr.\ 1 gesetzt ist:\quad + \lstinline{if (a & (1 << 1))} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsubsection + + C-Datentypen für Bit-Operationen: + \smallskip\par + \lstinline{#include <stdint.h>} + \medskip\par + \begin{tabular}{lllll} + & 8 Bit & 16 Bit & 32 Bit & 64 Bit \\ + mit Vorzeichen & \lstinline,int8_t, + & \lstinline,int16_t, + & \lstinline,int32_t, + & \lstinline,int64_t, \\ + ohne Vorzeichen & \lstinline,uint8_t, + & \lstinline,uint16_t, + & \lstinline,uint32_t, + & \lstinline,uint64_t, + \end{tabular} + + \bigskip + \bigskip + + Ausgabe: + \smallskip\par + \begin{lstlisting} + #include <stdio.h> + #include <stdint.h> + #include <inttypes.h> + ... + uint64_t x = 42; + printf ("Die Antwort lautet: %" PRIu64 "\n", x); + \end{lstlisting} + +\iffalse + + \bigskip + + Aufgabe: Schreiben Sie C-Funktionen, die ein "`Array von Bits"' realisieren, z.\,B. + + \smallskip + + \begin{tabular}[t]{ll} + \lstinline|void set_bit (int i);| & Bei Index $i$ auf 1 setzen \\ + \lstinline|void clear_bit (int i);| & Bei Index $i$ auf 0 setzen \\ + \lstinline|int get_bit (int i);| & Bei Index $i$ lesen + \end{tabular} + + \medskip + + Hinweise: + \begin{itemize} + \item + Die Größe des Bit-"`Arrays"' (z.\,B.\ 1000) dürfen Sie als \emph{vorher bekannt\/} voraussetzen. + \item + Sie benötigen ein Array, z.\,B.\ von \lstinline|char|- oder \lstinline|int|-Variablen. + \item + Sie benötigen eine Division (\lstinline|/|) sowie den Divisionsrest (Modulo: \lstinline|%|). + \end{itemize} + +\fi + +\end{frame} + +\subsection{I/O-Ports} + +\begin{frame}[fragile] + +% \showsection + \showsubsection + \vspace*{-1.5\medskipamount} + {\large\textbf{\color{structure}4.3\quad Interrupts}} + + \bigskip + + Kommunikation mit externen Geräten + + \bigskip + + \begin{center} + \includegraphics{io-ports-and-interrupts.pdf} + \end{center} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + In Output-Port schreiben = Aktoren ansteuern + + Beispiel: LED + + \medskip + + \begin{lstlisting} + #include <avr/io.h> + ... + DDRC = 0x70; + PORTC = 0x40; + \end{lstlisting} + \begin{picture}(0,0) + \put(3,0.67){\begin{minipage}{3cm} + \color{red}% + binär: 0111\,0000\\ + binär: 0100\,0000 + \end{minipage}} + \put(10,0.67){\makebox(0,0)[r]{\color{red}Herstellerspezifisch!}} + \end{picture} + + \bigskip + + \lstinline{DDR} = Data Direction Register\\ + Bit = 1 für Output-Port\\ + Bit = 0 für Input-Port + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Aus Input-Port lesen = Sensoren abfragen + + Beispiel: Taster + + \medskip + + \begin{lstlisting} + #include <avr/io.h> + ... + DDRC = 0xfd; + while ((PINC & 0x02) == 0) + ; /* just wait */ + \end{lstlisting} + \begin{picture}(0,0)(-1.5,-0.42) + \put(3,0.67){\begin{minipage}{3cm} + \color{red}% + binär: 1111\,1101\\ + binär: 0000\,0010 + \end{minipage}} + \put(10,0.67){\makebox(0,0)[r]{\color{red}Herstellerspezifisch!}} + \end{picture} + + \bigskip + + \lstinline{DDR} = Data Direction Register\\ + Bit = 1 für Output-Port\\ + Bit = 0 für Input-Port + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + + \bigskip + + Praktikumsaufgabe: Druckknopfampel + +\end{frame} + +\subsection{Interrupts} + +\begin{frame}[fragile] + + \showsubsection + + Externes Gerät ruft (per Stromsignal) Unterprogramm auf + + Zeiger hinterlegen: "`Interrupt-Vektor"' + + Beispiel: eingebaute Uhr\hfill + \makebox(0,0)[tr]{% + \only<1->{\begin{minipage}[t]{4.7cm} + \vspace*{-0.3cm}% + statt Zählschleife (\lstinline{_delay_ms}):\\ + Hauptprogramm kann\\ + andere Dinge tun + \end{minipage}}% + } + + \medskip + + \begin{lstlisting} + #include <avr/interrupt.h> + + ... + + + ISR (TIMER0B_COMP_vect) + { + PORTD ^= 0x40; + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(1.9,3.1){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-1.4,-1.0);}}} + \put(2.0,3.2){\makebox(0,0)[l]{"`Dies ist ein Interrupt-Handler."'}} + \put(2.3,2.6){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-0.6,-0.55);}}} + \put(2.4,2.6){\makebox(0,0)[l]{Interrupt-Vektor darauf zeigen lassen}} + \end{picture} + + Initialisierung über spezielle Ports: + \lstinline{TCCR0B}, \lstinline{TIMSK0} + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + + \vspace*{-2.5cm}\hfill + {\color{red}Herstellerspezifisch!}% + \hspace*{1cm} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Externes Gerät ruft (per Stromsignal) Unterprogramm auf + + Zeiger hinterlegen: "`Interrupt-Vektor"' + + Beispiel: Taster\hfill + \makebox(0,0)[tr]{% + \begin{minipage}[t]{4.7cm} + \vspace*{-0.3cm}% + statt \newterm{Busy Waiting\/}:\\ + Hauptprogramm kann\\ + andere Dinge tun + \end{minipage}} + + \medskip + + \begin{lstlisting} + #include <avr/interrupt.h> + ... + + ISR (INT0_vect) + { + PORTD ^= 0x40; + } + \end{lstlisting} + + \medskip + + Initialisierung über spezielle Ports: + \lstinline{EICRA}, \lstinline{EIMSK} + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + + \vspace*{-2.5cm}\hfill + {\color{red}Herstellerspezifisch!}% + \hspace*{1cm} + +\end{frame} + +\subsection{volatile-Variable} + +\begin{frame}[fragile] + + \showsubsection + + Externes Gerät ruft (per Stromsignal) Unterprogramm auf + + Zeiger hinterlegen: "`Interrupt-Vektor"' + + Beispiel: Taster + + \vspace*{-2.5pt} + + \begin{minipage}[t]{5cm} + \begin{onlyenv}<1> + \begin{lstlisting}[gobble=8] + ¡#include <avr/interrupt.h> + ... + + uint8_t key_pressed = 0; + + ISR (INT0_vect) + { + key_pressed = 1; + }¿ + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<2> + \begin{lstlisting}[gobble=8] + ¡#include <avr/interrupt.h> + ... + + volatile uint8_t key_pressed = 0; + + ISR (INT0_vect) + { + key_pressed = 1; + }¿ + \end{lstlisting} + \end{onlyenv} + \end{minipage}\hfill + \begin{minipage}[t]{6cm} + \begin{lstlisting}[gobble=6] + ¡int main (void) + { + ... + + while (1) + { + while (!key_pressed) + ; /* just wait */ + PORTD ^= 0x40; + key_pressed = 0; + } + return 0; + }¿ + \end{lstlisting} + \end{minipage} + + \pause + \begin{picture}(0,0) + \color{red} + \put(10.3,4.0){\makebox(0,0)[b]{\begin{minipage}{6cm} + \begin{center} + \textbf{volatile}:\\ + Speicherzugriff\\ + nicht wegoptimieren + \end{center} + \end{minipage}}} + \put(10.3,3.95){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-0.5,-0.9);}}} + \end{picture} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Was ist eigentlich \lstinline{PORTD}? + + \bigskip + \pause + + \lstinline[style=cmd]{avr-gcc -Wall -Os -mmcu=atmega328p blink-3.c -E} + + \bigskip + \pause + \lstinline{PORTD = 0x01;}\\ + \textarrow\quad + \lstinline[style=terminal]{(*(volatile uint8_t *)((0x0B) + 0x20)) = 0x01;}\\ + \pause + \begin{picture}(0,2)(0,-1.7) + \color{red} + \put(5.75,0.3){$\underbrace{\rule{2.95cm}{0pt}}_{\mbox{Zahl: \lstinline|0x2B|}}$} + \pause + \put(1.55,0.3){$\underbrace{\rule{4.0cm}{0pt}}_{\mbox{\shortstack[t]{Umwandlung in Zeiger\\ + auf \lstinline|volatile uint8_t|}}}$} + \pause + \put(1.32,-1){\makebox(0,0)[b]{\tikz{\draw[-latex](0,0)--(0,1.3)}}} + \put(1.12,-1.1){\makebox(0,0)[tl]{Dereferenzierung des Zeigers}} + \end{picture} + + \pause + \textarrow\quad + \lstinline|volatile uint8_t|-Variable an Speicheradresse \lstinline|0x2B| + + \pause + \bigskip + \bigskip + + \textarrow\quad + \lstinline|PORTA = PORTB = PORTC = PORTD = 0| ist eine schlechte Idee. + +\end{frame} + +\subsection{Byte-Reihenfolge -- Endianness} +\subsubsection{Konzept} + +\begin{frame}[fragile] + + \showsubsection + \showsubsubsection + + Eine Zahl geht über mehrere Speicherzellen.\\ + Beispiel: 16-Bit-Zahl in 2 8-Bit-Speicherzellen + + \smallskip + + Welche Bits liegen wo? + +% \pause + \bigskip + + $1027 = 1024 + 2 + 1 = 0000\,0100\,0000\,0011_2 = 0403_{16}$ + +% \pause + \bigskip + Speicherzellen: + + \medskip + \begin{tabular}{|c|c|l}\cline{1-2} + \raisebox{-0.25ex}{04} & \raisebox{-0.25ex}{03} & \strut Big-Endian "`großes Ende zuerst"' \\\cline{1-2} + \multicolumn{2}{c}{} & % \pause + für Menschen leichter lesbar % \pause + \\ + \multicolumn{3}{c}{} \\[-5pt]\cline{1-2} + \raisebox{-0.25ex}{03} & \raisebox{-0.25ex}{04} & \strut Little-Endian "`kleines Ende zuerst"' \\\cline{1-2} + \multicolumn{2}{c}{} & % \pause + bei Additionen effizienter + \end{tabular} + +% \pause + \medskip + \textarrow\ Geschmackssache +% \pause\\ + \quad\textbf{\dots\ außer bei Datenaustausch!} + +% \pause +% \bigskip +% +% Aber: nicht verwechseln! \qquad $0304_{16} = 772$ + +\end{frame} + +\begin{frame} + + \showsubsection + \showsubsubsection + + Eine Zahl geht über mehrere Speicherzellen.\\ + Beispiel: 16-Bit-Zahl in 2 8-Bit-Speicherzellen + + \smallskip + + Welche Bits liegen wo? + + \medskip + + \textarrow\ Geschmackssache\\ + \textbf{\dots\ außer bei Datenaustausch!} + + \begin{itemize} + \item + Dateiformate + \item + Datenübertragung + \end{itemize} + +\end{frame} + +\subsubsection{Dateiformate} + +\begin{frame} + + \showsubsection + \showsubsubsection + + Audio-Formate: Reihenfolge der Bytes in 16- und 32-Bit-Zahlen + \begin{itemize} + \item + RIFF-WAVE-Dateien (\file{.wav}): Little-Endian + \item + Au-Dateien (\file{.au}): Big-Endian +% \pause + \item + ältere AIFF-Dateien (\file{.aiff}): Big-Endian + \item + neuere AIFF-Dateien (\file{.aiff}): Little-Endian + \end{itemize} + +% \pause + \bigskip + + Grafik-Formate: Reihenfolge der Bits in den Bytes + \begin{itemize} + \item + PBM-Dateien: Big-Endian\only<1->{, MSB first} + \item + XBM-Dateien: Little-Endian\only<1->{, LSB first} + \end{itemize} + \only<1->{MSB/LSB = most/least significant bit} + +\end{frame} + +\subsubsection{Datenübertragung} + +\begin{frame} + + \showsubsection + \showsubsubsection + + \begin{itemize} + \item + RS-232 (serielle Schnittstelle): LSB first + \item + I$^2$C: MSB first + \item + USB: beides + \pause + \medskip + \item + Ethernet: LSB first + \item + TCP/IP (Internet): Big-Endian + \end{itemize} + +\end{frame} + +\iffalse + +\subsection{Binärdarstellung negativer Zahlen} + +\begin{frame}[fragile] + + \showsubsection + + Speicher ist begrenzt!\\ + \textarrow\ feste Anzahl von Bits + + \medskip + + 8-Bit-Zahlen ohne Vorzeichen: \lstinline{uint8_t}\\ + \textarrow\ Zahlenwerte von \lstinline{0x00} bis \lstinline{0xff} = 0 bis 255\\ + \pause + \textarrow\ 255 + 1 = 0 + + \pause + \medskip + + 8-Bit-Zahlen mit Vorzeichen: \lstinline{int8_t}\\ + \lstinline{0xff} = 255 ist die "`natürliche"' Schreibweise für $-1$.\\ + \pause + \textarrow\ Zweierkomplement + + \pause + \medskip + + Oberstes Bit = 1: negativ\\ + Oberstes Bit = 0: positiv\\ + \textarrow\ 127 + 1 = $-128$ + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Speicher ist begrenzt!\\ + \textarrow\ feste Anzahl von Bits + + \medskip + + 16-Bit-Zahlen ohne Vorzeichen: + \lstinline{uint16_t}\hfill\lstinline{uint8_t}\\ + \textarrow\ Zahlenwerte von \lstinline{0x0000} bis \lstinline{0xffff} + = 0 bis 65535\hfill 0 bis 255\\ + \textarrow\ 65535 + 1 = 0\hfill 255 + 1 = 0 + + \medskip + + 16-Bit-Zahlen mit Vorzeichen: + \lstinline{int16_t}\hfill\lstinline{int8_t}\\ + \lstinline{0xffff} = 66535 ist die "`natürliche"' Schreibweise für $-1$.\hfill + \lstinline{0xff} = 255 = $-1$\\ + \textarrow\ Zweierkomplement + + \medskip + + Oberstes Bit = 1: negativ\\ + Oberstes Bit = 0: positiv\\ + \textarrow\ 32767 + 1 = $-32768$ + + \bigskip + Literatur: \url{http://xkcd.com/571/} + +\end{frame} + +\fi + +\begin{frame}[fragile] + + \showsubsection + + Frage: \emph{Für welche Zahl steht der Speicherinhalt\, + \raisebox{2pt}{% + \tabcolsep0.25em + \begin{tabular}{|c|c|}\hline + \rule{0pt}{11pt}a3 & 90 \\\hline + \end{tabular}} + (hexadezimal)?} + + \pause + \smallskip + Antwort: \emph{Das kommt darauf an.} ;--) + + \pause + \medskip + Little-Endian: + + \smallskip + + \begin{tabular}{lrl} + als \lstinline,int8_t,: & $-93$ & (nur erstes Byte)\\ + als \lstinline,uint8_t,: & $163$ & (nur erstes Byte)\\ + als \lstinline,int16_t,: & $-28509$\\ + als \lstinline,uint16_t,: & $37027$\\ + \lstinline,int32_t, oder größer: & $37027$ + & (zusätzliche Bytes mit Nullen aufgefüllt) + \end{tabular} + + \pause + \medskip + Big-Endian: + + \smallskip + + \begin{tabular}{lrl} + als \lstinline,int8_t,: & $-93$ & (nur erstes Byte)\\ + als \lstinline,uint8_t,: & $163$ & (nur erstes Byte)\\ + als \lstinline,int16_t,: & $-23664$\\ + als \lstinline,uint16_t,: & $41872$\\ als \lstinline,int32_t,: & $-1550843904$ & (zusätzliche Bytes\\ + als \lstinline,uint32_t,: & $2744123392$ & mit Nullen aufgefüllt)\\ + als \lstinline,int64_t,: & $-6660823848880963584$\\ + als \lstinline,uint64_t,: & $11785920224828588032$\\ + \end{tabular} + + \vspace*{-1cm} + +\end{frame} + +\subsection{Speicherausrichtung -- Alignment} + +\begin{frame}[fragile] + + \showsubsection + + \begin{lstlisting} + #include <stdint.h> + + uint8_t a; + uint16_t b; + uint8_t c; + \end{lstlisting} + + \pause + \bigskip + + Speicheradresse durch 2 teilbar -- "`16-Bit-Alignment"' + \begin{itemize} + \item + 2-Byte-Operation: effizienter + \pause + \item + \dots\ oder sogar nur dann erlaubt + \pause + \arrowitem + Compiler optimiert Speicherausrichtung + \end{itemize} + + \medskip + + \pause + \begin{minipage}{3cm} + \begin{lstlisting}[gobble=6] + ¡uint8_t a; + uint8_t dummy; + uint16_t b; + uint8_t c;¿ + \end{lstlisting} + \end{minipage} + \pause + \begin{minipage}{3cm} + \begin{lstlisting}[gobble=6] + ¡uint8_t a; + uint8_t c; + uint16_t b;¿ + \end{lstlisting} + \end{minipage} + + \pause + \vspace{-1.75cm} + \strut\hfill + \begin{minipage}{6.5cm} + Fazit: + \begin{itemize} + \item + \textbf{Adressen von Variablen\\ + sind systemabhängig} + \item + Bei Definition von Datenformaten\\ + Alignment beachten \textarrow\ effizienter + \end{itemize} + \end{minipage} + +\end{frame} + +\end{document} diff --git a/20230523/rtech-20230523.txt b/20230523/rtech-20230523.txt new file mode 100644 index 0000000000000000000000000000000000000000..5dfc1acdf4a45b29a742f592c7c20bf3fbdfb545 --- /dev/null +++ b/20230523/rtech-20230523.txt @@ -0,0 +1,15 @@ +Stack-Alignment beim Aufruf von printf(), 23.05.2023, 12:48:23 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +https://stackoverflow.com/questions/38335212/calling-printf-in-x86-64-using-gnu-assembler + +Vor dem Aufruf von printf() muß der Stack auf 16 oder 32 Bytes +ausgerichtet sein (16- bzw. 32-Byte-Alignment). + +32 Bytes sind notwendig, wenn das Vektor-Register __m256 +auf den Stack gelegt wird. + +Innerhalb von main(): Stack nur auf 8 Bytes ausgerichtet. +Wir subtrahieren 24 von %rsp, bevor wir printf() aufrufen. +8 von diesen 24 Bytes verwenden wir für Variable. + +Bei ARMv7-A (32 Bit) scheint ein 8- oder 16-Byte-Alignment zu genügen. diff --git a/20230523/test-arm-01.c b/20230523/test-arm-01.c new file mode 100644 index 0000000000000000000000000000000000000000..85b2c1b01ca06395f2e33d984058e595a7607fc0 --- /dev/null +++ b/20230523/test-arm-01.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +int main (void) +{ + volatile int a = 7; + volatile int b = 6; + printf ("a + b = %d\n", a + b); + return 0; +} diff --git a/20230523/test-arm-01.s-arm b/20230523/test-arm-01.s-arm new file mode 100644 index 0000000000000000000000000000000000000000..1e0aaf0a4d9f2bf069a6b907e806f3d4ca08cb37 --- /dev/null +++ b/20230523/test-arm-01.s-arm @@ -0,0 +1,52 @@ + .arch armv7-a + .eabi_attribute 28, 1 + .eabi_attribute 20, 1 + .eabi_attribute 21, 1 + .eabi_attribute 23, 3 + .eabi_attribute 24, 1 + .eabi_attribute 25, 1 + .eabi_attribute 26, 2 + .eabi_attribute 30, 1 + .eabi_attribute 34, 1 + .eabi_attribute 18, 4 + .file "test-arm-01.c" + .text + .align 1 + .global main + .arch armv7-a + .syntax unified + .thumb + .thumb_func + .fpu vfpv3-d16 + .type main, %function +main: + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + push {lr} + sub sp, sp, #12 + movs r3, #7 + str r3, [sp, #4] + movs r3, #6 + str r3, [sp] + ldr r1, [sp, #4] + ldr r3, [sp] + add r1, r1, r3 + ldr r0, .L3 +.LPIC0: + add r0, pc + bl printf(PLT) + movs r0, #0 + add sp, sp, #12 + @ sp needed + ldr pc, [sp], #4 +.L4: + .align 2 +.L3: + .word .LC0-(.LPIC0+4) + .size main, .-main + .section .rodata.str1.4,"aMS",%progbits,1 + .align 2 +.LC0: + .ascii "a + b = %d\012\000" + .ident "GCC: (Debian 8.3.0-2) 8.3.0" + .section .note.GNU-stack,"",%progbits diff --git a/20230523/test-arm-01.s-x86 b/20230523/test-arm-01.s-x86 new file mode 100644 index 0000000000000000000000000000000000000000..bad49f5c5e8abe5950880119081f4e59125fdbf7 --- /dev/null +++ b/20230523/test-arm-01.s-x86 @@ -0,0 +1,30 @@ + .file "test-arm-01.c" + .text + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "a + b = %d\n" + .text + .globl main + .type main, @function +main: +.LFB11: + .cfi_startproc + subq $24, %rsp + .cfi_def_cfa_offset 32 + movl $7, 12(%rsp) + movl $6, 8(%rsp) + movl 12(%rsp), %esi + movl 8(%rsp), %eax + addl %eax, %esi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + movl $0, %eax + addq $24, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE11: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/test-arm-01.s-x86-Os b/20230523/test-arm-01.s-x86-Os new file mode 100644 index 0000000000000000000000000000000000000000..c51719a60a2196bb06dc3653fea960e76ea0c814 --- /dev/null +++ b/20230523/test-arm-01.s-x86-Os @@ -0,0 +1,30 @@ + .file "test-arm-01.c" + .text + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "a + b = %d\n" + .section .text.startup,"ax",@progbits + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + subq $24, %rsp + .cfi_def_cfa_offset 32 + leaq .LC0(%rip), %rdi + movl $7, 8(%rsp) + movl $6, 12(%rsp) + movl 8(%rsp), %esi + movl 12(%rsp), %eax + addl %eax, %esi + xorl %eax, %eax + call printf@PLT + xorl %eax, %eax + addq $24, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE0: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/test-arm-02.c b/20230523/test-arm-02.c new file mode 100644 index 0000000000000000000000000000000000000000..92b34cb57211e862806e3a6fc924f8b0e8b11b54 --- /dev/null +++ b/20230523/test-arm-02.c @@ -0,0 +1,8 @@ +#include <stdio.h> + +int main (void) +{ + volatile int a = 7; + volatile int b = 6; + return 0; +} diff --git a/20230523/test-arm-02.s-arm b/20230523/test-arm-02.s-arm new file mode 100644 index 0000000000000000000000000000000000000000..637f89b31208cf82fa9f2fe479124bb938948cc2 --- /dev/null +++ b/20230523/test-arm-02.s-arm @@ -0,0 +1,37 @@ + .arch armv7-a + .eabi_attribute 28, 1 + .eabi_attribute 20, 1 + .eabi_attribute 21, 1 + .eabi_attribute 23, 3 + .eabi_attribute 24, 1 + .eabi_attribute 25, 1 + .eabi_attribute 26, 2 + .eabi_attribute 30, 1 + .eabi_attribute 34, 1 + .eabi_attribute 18, 4 + .file "test-arm-02.c" + .text + .align 1 + .global main + .arch armv7-a + .syntax unified + .thumb + .thumb_func + .fpu vfpv3-d16 + .type main, %function +main: + @ args = 0, pretend = 0, frame = 8 + @ frame_needed = 0, uses_anonymous_args = 0 + @ link register save eliminated. + sub sp, sp, #8 + movs r3, #7 + str r3, [sp, #4] + movs r3, #6 + str r3, [sp] + movs r0, #0 + add sp, sp, #8 + @ sp needed + bx lr + .size main, .-main + .ident "GCC: (Debian 8.3.0-2) 8.3.0" + .section .note.GNU-stack,"",%progbits diff --git a/20230523/test-arm-02.s-avr b/20230523/test-arm-02.s-avr new file mode 100644 index 0000000000000000000000000000000000000000..c6153696a5df5e0737d0cef96ff1de601cd198ae --- /dev/null +++ b/20230523/test-arm-02.s-avr @@ -0,0 +1,40 @@ + .file "test-arm-02.c" +__SP_H__ = 0x3e +__SP_L__ = 0x3d +__SREG__ = 0x3f +__tmp_reg__ = 0 +__zero_reg__ = 1 + .text +.global main + .type main, @function +main: + push r28 + push r29 + rcall . + rcall . + in r28,__SP_L__ + in r29,__SP_H__ +/* prologue: function */ +/* frame size = 4 */ +/* stack size = 6 */ +.L__stack_usage = 6 + ldi r24,lo8(7) + ldi r25,0 + std Y+2,r25 + std Y+1,r24 + ldi r24,lo8(6) + ldi r25,0 + std Y+4,r25 + std Y+3,r24 + ldi r24,0 + ldi r25,0 +/* epilogue start */ + pop __tmp_reg__ + pop __tmp_reg__ + pop __tmp_reg__ + pop __tmp_reg__ + pop r29 + pop r28 + ret + .size main, .-main + .ident "GCC: (GNU) 5.4.0" diff --git a/20230523/test-arm-02.s-x86 b/20230523/test-arm-02.s-x86 new file mode 100644 index 0000000000000000000000000000000000000000..b7f6937357a65d11cf0c29249db32c456399d989 --- /dev/null +++ b/20230523/test-arm-02.s-x86 @@ -0,0 +1,16 @@ + .file "test-arm-02.c" + .text + .globl main + .type main, @function +main: +.LFB11: + .cfi_startproc + movl $7, -4(%rsp) + movl $6, -8(%rsp) + movl $0, %eax + ret + .cfi_endproc +.LFE11: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/test-arm-03.c b/20230523/test-arm-03.c new file mode 100644 index 0000000000000000000000000000000000000000..1dc41ef41d035afe7575f553be73ebecfbb5ad87 --- /dev/null +++ b/20230523/test-arm-03.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +int main (void) +{ + volatile int a = 7; + volatile int b = 6; + volatile int c = 9; + volatile int d = 11; + return 0; +} diff --git a/20230523/test-arm-03.s-x86 b/20230523/test-arm-03.s-x86 new file mode 100644 index 0000000000000000000000000000000000000000..d04b263b58c2b8de8df09b40edb822843290b332 --- /dev/null +++ b/20230523/test-arm-03.s-x86 @@ -0,0 +1,18 @@ + .file "test-arm-03.c" + .text + .globl main + .type main, @function +main: +.LFB11: + .cfi_startproc + movl $7, -4(%rsp) + movl $6, -8(%rsp) + movl $9, -12(%rsp) + movl $11, -16(%rsp) + movl $0, %eax + ret + .cfi_endproc +.LFE11: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/test-arm-04.c b/20230523/test-arm-04.c new file mode 100644 index 0000000000000000000000000000000000000000..acbd05c4c5099ceb9167591776a3078093eb0f88 --- /dev/null +++ b/20230523/test-arm-04.c @@ -0,0 +1,11 @@ +#include <stdio.h> + +int main (void) +{ + volatile int a = 7; + volatile int b = 6; + volatile int c = 9; + volatile int d = 11; + volatile int e = 13; + return 0; +} diff --git a/20230523/test-arm-04.s-x86 b/20230523/test-arm-04.s-x86 new file mode 100644 index 0000000000000000000000000000000000000000..379ed72ff61e13c7cfe37d77dde8746806ec635a --- /dev/null +++ b/20230523/test-arm-04.s-x86 @@ -0,0 +1,19 @@ + .file "test-arm-04.c" + .text + .globl main + .type main, @function +main: +.LFB11: + .cfi_startproc + movl $7, -4(%rsp) + movl $6, -8(%rsp) + movl $9, -12(%rsp) + movl $11, -16(%rsp) + movl $13, -20(%rsp) + movl $0, %eax + ret + .cfi_endproc +.LFE11: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230523/test-arm-05.c b/20230523/test-arm-05.c new file mode 100644 index 0000000000000000000000000000000000000000..21e888bc8da4f8efc36d567f9ce2423a43d2b7b1 --- /dev/null +++ b/20230523/test-arm-05.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +int main (void) +{ + volatile int a = 7; + volatile int b = 6; + volatile int c = 9; + volatile int d = 11; + volatile int e = 13; + volatile int f = 17; + return 0; +} diff --git a/20230523/test-arm-05.s-x86 b/20230523/test-arm-05.s-x86 new file mode 100644 index 0000000000000000000000000000000000000000..cc84fec597a9d8820cbbce111628bd1163980dfd --- /dev/null +++ b/20230523/test-arm-05.s-x86 @@ -0,0 +1,20 @@ + .file "test-arm-05.c" + .text + .globl main + .type main, @function +main: +.LFB11: + .cfi_startproc + movl $7, -4(%rsp) + movl $6, -8(%rsp) + movl $9, -12(%rsp) + movl $11, -16(%rsp) + movl $13, -20(%rsp) + movl $17, -24(%rsp) + movl $0, %eax + ret + .cfi_endproc +.LFE11: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230524/buffer-overflow-01.c b/20230524/buffer-overflow-01.c new file mode 100644 index 0000000000000000000000000000000000000000..8dfffe01cad1ffff228ad41d8df48eefe995a9a8 --- /dev/null +++ b/20230524/buffer-overflow-01.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +int main (void) +{ + char name[10]; + printf ("Ihr Name: "); + scanf ("%s", name); + printf ("Hallo, %s! :-)\n", name); + return 0; +} diff --git a/20230524/buffer-overflow-02.c b/20230524/buffer-overflow-02.c new file mode 100644 index 0000000000000000000000000000000000000000..dd84b2a3e2ad0a8c59d50adb897363c24e7492cf --- /dev/null +++ b/20230524/buffer-overflow-02.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +int main (void) +{ + char name[10]; + printf ("Ihr Name: "); + gets (name); + printf ("Hallo, %s! :-)\n", name); + return 0; +} diff --git a/20230524/io-ports-and-interrupts.pdf b/20230524/io-ports-and-interrupts.pdf new file mode 120000 index 0000000000000000000000000000000000000000..bcd46f7afb35605b20bdb05637e6de0a039893ec --- /dev/null +++ b/20230524/io-ports-and-interrupts.pdf @@ -0,0 +1 @@ +../common/io-ports-and-interrupts.pdf \ No newline at end of file diff --git a/20230524/logo-hochschule-bochum-cvh-text-v2.pdf b/20230524/logo-hochschule-bochum-cvh-text-v2.pdf new file mode 120000 index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8 --- /dev/null +++ b/20230524/logo-hochschule-bochum-cvh-text-v2.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum-cvh-text-v2.pdf \ No newline at end of file diff --git a/20230524/logo-hochschule-bochum.pdf b/20230524/logo-hochschule-bochum.pdf new file mode 120000 index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1 --- /dev/null +++ b/20230524/logo-hochschule-bochum.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum.pdf \ No newline at end of file diff --git a/20230524/parameters-01-O0-stack-4.s b/20230524/parameters-01-O0-stack-4.s new file mode 100644 index 0000000000000000000000000000000000000000..7bc17075e04e3c7aa51fa4abfb0d0992ef7f9240 --- /dev/null +++ b/20230524/parameters-01-O0-stack-4.s @@ -0,0 +1,56 @@ + .file "parameters-01.c" + .text + .globl sum + .type sum, @function +sum: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -4(%rbp) + movl %esi, -8(%rbp) + movl -4(%rbp), %edx + movl -8(%rbp), %eax + addl %edx, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size sum, .-sum + .section .rodata +.LC0: + .string "c = %d\n" + .text + .globl main + .type main, @function +main: # #include <stdio.h> +.LFB1: # + .cfi_startproc # int sum (int a, int b) + pushq %rbp # { + .cfi_def_cfa_offset 16 # return a + b; + .cfi_offset 6, -16 # } + movq %rsp, %rbp # + .cfi_def_cfa_register 6 # int main (void) + subq $5, %rsp # vorher: 16 # { + movl $6, %esi # int c = sum (7, 6); + movl $7, %edi # printf ("c = %d\n", c); + call sum # return 0; + movl %eax, -4(%rbp) # } + movl -4(%rbp), %eax + movl %eax, %esi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + movl $0, %eax + leave # leave = movq %rbp, %rsp + .cfi_def_cfa 7, 8 # popq %rbp + ret + .cfi_endproc +.LFE1: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230524/parameters-01-O0.s b/20230524/parameters-01-O0.s new file mode 100644 index 0000000000000000000000000000000000000000..7b4fc50269473d9b813eaa111df5fee4e52e2278 --- /dev/null +++ b/20230524/parameters-01-O0.s @@ -0,0 +1,56 @@ + .file "parameters-01.c" + .text + .globl sum + .type sum, @function +sum: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movl %edi, -4(%rbp) + movl %esi, -8(%rbp) + movl -4(%rbp), %edx + movl -8(%rbp), %eax + addl %edx, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size sum, .-sum + .section .rodata +.LC0: + .string "c = %d\n" + .text + .globl main + .type main, @function +main: ; #include <stdio.h> +.LFB1: ; + .cfi_startproc ; int sum (int a, int b) + pushq %rbp ; { + .cfi_def_cfa_offset 16 ; return a + b; + .cfi_offset 6, -16 ; } + movq %rsp, %rbp ; + .cfi_def_cfa_register 6 ; int main (void) + subq $16, %rsp ; { + movl $6, %esi ; int c = sum (7, 6); + movl $7, %edi ; printf ("c = %d\n", c); + call sum ; return 0; + movl %eax, -4(%rbp) ; } + movl -4(%rbp), %eax + movl %eax, %esi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + movl $0, %eax + leave ; leave = movq %rbp, %rsp + .cfi_def_cfa 7, 8 ; popq %rbp + ret + .cfi_endproc +.LFE1: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230524/parameters-01.c b/20230524/parameters-01.c new file mode 100644 index 0000000000000000000000000000000000000000..7b973a073bb12dd15c596306dbbb8476cbb599fa --- /dev/null +++ b/20230524/parameters-01.c @@ -0,0 +1,13 @@ +#include <stdio.h> + +int sum (int a, int b) +{ + return a + b; +} + +int main (void) +{ + int c = sum (7, 6); + printf ("c = %d\n", c); + return 0; +} diff --git a/20230524/parameters-01.s b/20230524/parameters-01.s new file mode 100644 index 0000000000000000000000000000000000000000..cdaaee416e623d8ee3999ef75868c8f30d02ae84 --- /dev/null +++ b/20230524/parameters-01.s @@ -0,0 +1,36 @@ + .file "parameters-01.c" + .text + .globl sum + .type sum, @function +sum: +.LFB11: + .cfi_startproc + leal (%rdi,%rsi), %eax + ret + .cfi_endproc +.LFE11: + .size sum, .-sum + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "c = %d\n" + .text + .globl main + .type main, @function +main: ; #include <stdio.h> +.LFB12: ; + .cfi_startproc ; int sum (int a, int b) + subq $8, %rsp ; { + .cfi_def_cfa_offset 16 ; return a + b; + movl $13, %esi ; } + leaq .LC0(%rip), %rdi ; + movl $0, %eax ; int main (void) + call printf@PLT ; { + movl $0, %eax ; int c = sum (7, 6); + addq $8, %rsp ; printf ("c = %d\n", c); + .cfi_def_cfa_offset 8 ; return 0; + ret ; } + .cfi_endproc +.LFE12: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230524/parameters-02.c b/20230524/parameters-02.c new file mode 100644 index 0000000000000000000000000000000000000000..95f916da0ac0f5d7f194f17b4af8d548402afd86 --- /dev/null +++ b/20230524/parameters-02.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +void print (int h, int e, int l1, int l2, int o1, + int comma, int space, + int w, int o2, int r, int l3, int d, + int bang, int newline) +{ + printf ("%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + h, e, l1, l2, o1, comma, space, w, o2, r, l3, d, bang, newline); +} + +int main (void) +{ + print ('H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\n'); + return 0; +} diff --git a/20230524/parameters-02.s b/20230524/parameters-02.s new file mode 100644 index 0000000000000000000000000000000000000000..c6d3a6b1890546168305088a5d77fe596747f927 --- /dev/null +++ b/20230524/parameters-02.s @@ -0,0 +1,92 @@ + .file "parameters-02.c" + .text + .section .rodata.str1.1,"aMS",@progbits,1 +.LC0: + .string "%c%c%c%c%c%c%c%c%c%c%c%c%c%c" + .text + .globl print + .type print, @function +print: +.LFB11: + .cfi_startproc + subq $16, %rsp + .cfi_def_cfa_offset 24 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 32 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 40 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 48 + movl 80(%rsp), %eax + pushq %rax + .cfi_def_cfa_offset 56 + movl 80(%rsp), %eax # #include <stdio.h> + pushq %rax # + .cfi_def_cfa_offset 64 # void print (int h, int e, int l1, int l2, int o1, + movl 80(%rsp), %eax # int comma, int space, + pushq %rax # int w, int o2, int r, int l3, int d, + .cfi_def_cfa_offset 72 # int bang, int newline) + movl 80(%rsp), %eax # { + pushq %rax # printf ("%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + .cfi_def_cfa_offset 80 # h, e, l1, l2, o1, comma, space, w, o2, r, l3, d, bang, newline); + movl 80(%rsp), %eax # } + pushq %rax # + .cfi_def_cfa_offset 88 # int main (void) + pushq %r9 # { + .cfi_def_cfa_offset 96 # print ('H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\n'); + movl %r8d, %r9d # return 0; + movl %ecx, %r8d + movl %edx, %ecx + movl %esi, %edx + movl %edi, %esi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + addq $88, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE11: + .size print, .-print + .globl main + .type main, @function +main: +.LFB12: + .cfi_startproc + subq $8, %rsp + .cfi_def_cfa_offset 16 + pushq $10 + .cfi_def_cfa_offset 24 + pushq $33 + .cfi_def_cfa_offset 32 + pushq $100 + .cfi_def_cfa_offset 40 + pushq $108 + .cfi_def_cfa_offset 48 + pushq $114 + .cfi_def_cfa_offset 56 + pushq $111 + .cfi_def_cfa_offset 64 + pushq $119 + .cfi_def_cfa_offset 72 + pushq $32 + .cfi_def_cfa_offset 80 + movl $44, %r9d + movl $111, %r8d + movl $108, %ecx + movl $108, %edx + movl $101, %esi + movl $72, %edi + call print + movl $0, %eax + addq $72, %rsp + .cfi_def_cfa_offset 8 + ret + .cfi_endproc +.LFE12: + .size main, .-main + .ident "GCC: (Debian 8.3.0-6) 8.3.0" + .section .note.GNU-stack,"",@progbits diff --git a/20230524/pgslides.sty b/20230524/pgslides.sty new file mode 120000 index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64 --- /dev/null +++ b/20230524/pgslides.sty @@ -0,0 +1 @@ +../common/pgslides.sty \ No newline at end of file diff --git a/20230524/rtech-20230524.pdf b/20230524/rtech-20230524.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3753b8be31a31e77418d889aa7e876c3d2265de2 Binary files /dev/null and b/20230524/rtech-20230524.pdf differ diff --git a/20230524/rtech-20230524.tex b/20230524/rtech-20230524.tex new file mode 100644 index 0000000000000000000000000000000000000000..f384fce8cc1c0d8b45d03f4128a4d9b130ac9e12 --- /dev/null +++ b/20230524/rtech-20230524.tex @@ -0,0 +1,1761 @@ +% rtech-20230524.pdf - Lecture Slides on Computer Technology +% Copyright (C) 2012, 2013, 2014, 2021, 2022, 2023 Peter Gerwinski +% +% This document is free software: you can redistribute it and/or +% modify it either under the terms of the Creative Commons +% Attribution-ShareAlike 3.0 License, or under the terms of the +% GNU General Public License as published by the Free Software +% Foundation, either version 3 of the License, or (at your option) +% any later version. +% +% This document is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this document. If not, see <http://www.gnu.org/licenses/>. +% +% You should have received a copy of the Creative Commons +% Attribution-ShareAlike 3.0 Unported License along with this +% document. If not, see <http://creativecommons.org/licenses/>. + +% README: Der CPU-Stack, hardwarenahe Programmierung + +\documentclass[10pt,t]{beamer} + +\usepackage{pgslides} +\usepackage{pdftricks} +%\usepackage[obeyfamily=false,mathrm=mathsf,textrm=sffamily]{siunitx} +%\usepackage{eurosym} +\usepackage{tikz} + +\newcommand{\Cin}{C\raisebox{-0.5ex}{\footnotesize in}} +\newcommand{\Cout}{C\raisebox{-0.5ex}{\footnotesize out}} + +\lstdefinestyle{asm}{basicstyle=\color{structure}, + language={}, + gobble=4} + +\begin{psinputs} + \usepackage[utf8]{inputenc} + \usepackage[german]{babel} + \usepackage[T1]{fontenc} + \usepackage{helvet} + \renewcommand*\familydefault{\sfdefault} + \usepackage{pstricks,pst-grad,pst-circ-pg} + \newcommand{\invisible}{\tiny\color{white}} + \psset{unit=1cm} + \psset{logicLabelstyle=\invisible} + \newcommand{\logicSymbol}{\small\boldmath\bf\rule{0pt}{0.5cm}} + \psset{logicSymbolstyle=\logicSymbol} + \newcommand{\Cin}{C\raisebox{-0.5ex}{\footnotesize in}} + \newcommand{\Cout}{C\raisebox{-0.5ex}{\footnotesize out}} +\end{psinputs} + +\title{Rechnertechnik} +\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski} +\date{24.\ Mai 2022} + +\begin{document} + +\maketitleframe + +\nosectionnonumber{\inserttitle} + +\begin{frame} + + \shownosectionnonumber + + \begin{itemize} + \item[\textbf{1}] \textbf{Einführung} + \item[\textbf{2}] \textbf{Vom Schaltkreis zum Computer} + \item[\textbf{3}] \textbf{Assember-Programmierung} + \begin{itemize} + \item[3.1] Struktur von Assembler-Programmen + \item[3.2] Beispiel: Redcode + \color{medgreen} + \item[3.3] Architekturmerkmale von Prozessore + \color{orange} + \item[3.4] Der CPU-Stack + \color{red} + \item[3.5] Computer-Sprachen + \end{itemize} +% \color{gray} + \item[\textbf{4}] \textbf{Hardwarenahe Programmierung} +% \item[\textbf{6}] \textbf{Anwender-Software} +% \item[\textbf{7}] \textbf{Bus-Systeme} +% \item[\textbf{8}] \textbf{Pipelining} +% \item[\textbf{9}] \textbf{Ausblick} + \item[\textbf{\dots\hspace{-0.75em}}] + \end{itemize} + +\end{frame} + +\setcounter{section}{2} +\section{Assembler-Programmierung} +\setcounter{subsection}{2} +\subsection{Architekturmerkmale von Prozessoren} +\subsubsection{Speicherarchitekturen} + +\begin{frame} + + \showsubsection + + Oder: Jede Assembler-Sprache ist anders. + + \bigskip + + \showsubsubsection + + Bezeichnungen + \begin{itemize} + \item + \newterm{Bit\/} = 0 oder 1 -- kleinste Einheit an Information + \item + \newterm{Byte\/} = Zusammenfassung mehrerer \newterm{Bits}\\ + zu einer Binärzahl, die ein Zeichen (\newterm{Character\/}) darstellen kann,\\ + häufig 8 Bits (\newterm{Oktett\/}) + \item + \newterm{Speicherwort\/} = Zusammenfassung mehrerer Bits\\ + zu der kleinsten adressierbaren Einheit, häufig 1 Byte + \item + \newterm{RAM\/} = \newterm{Random Access Memory\/} = Hauptspeicher + \item + \newterm{ROM\/} = \newterm{Read Only Memory\/} = nur lesbarer Speicher + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsubsection + + Verschiedene Arten von Speicher + \begin{itemize} + \item + \newterm{Prozessor-Register}\\ + können direkt mit ALU verbunden werden,\\ + besonders schnell (Flipflops),\\ + überschaubare Anzahl von Registern + \item + \newterm{Hauptspeicher}\\ + kann direkt adressiert und mit Prozessor-Registern abgeglichen werden,\\ + heute i.\,d.\,R.\ dynamischer Speicher (Kondensatoren) + \item + \newterm{I/O-Ports}\\ + sind spezielle Speicheradressen, über die\\ + mit externen Geräten kommuniziert wird + \item + \newterm{Massenspeicher}\\ + liegt auf externem Gerät, wird über I/O-Ports angesprochen,\\ + Festplatte, Flash-Speicher, \dots + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsubsubsection + + \begin{itemize} + \item + \newterm{Von-Neumann-Architektur}\\ + Es gibt nur 1 Hauptspeicher, in dem sich sowohl die Befehle\\ + als auch die Daten befinden. + + \begin{onlyenv}<1> + \smallskip + + Vorteil: Flexibilität in der Speichernutzung + + Nachteil: Befehle können überschrieben werden.\\ + $\longrightarrow$ Abstürze und Malware möglich + \end{onlyenv} + + \pause + \item + \newterm{Harvard-Architektur}\\ + Es gibt 2 Hauptspeicher. In einem befinden sich die Befehle,\\ + im anderen die Daten. + + \begin{onlyenv}<2> + \smallskip + + Vorteil: Befehle können nicht überschrieben werden\\ + $\longrightarrow$ sicherer als Von-Neumann-Architektur + + Nachteile: Leitungen zum Speicher (Bus) müssen doppelt vorhanden sein,\\ + freier Befehlsspeicher kann nicht für Daten genutzt werden. + \end{onlyenv} + + \pause + \item + Weitere Kombinationen\\ + Hauptspeicher und I/O-Ports gemeinsam oder getrennt,\\ + Hauptspeicher und Prozessorregister gemeinsam oder getrennt + \end{itemize} + +\end{frame} + +\begin{frame} + + \showsubsubsection + + Beispiele: + \begin{itemize} + \item + Intel IA-32, AMD64:\\ + Von-Neumann-Architektur (plus Speicherschutzmechanismen),\\ + Prozessorregister und I/O-Ports vom Hauptspeicher getrennt + \item + Atmel AVR (z.\,B.\ ATmega):\\ + Harvard-Architektur\\ + (Befehlsspeicher als Flash-Speicher grundsätzlich auch schreibbar),\\ + Prozessorregister und I/O-Ports in gemeinsamem Adressbereich mit Hauptspeicher + \item + 6502, Renesas 740-CPU, Renesas-38000-Mikrocontroller:\\ + Von-Neumann-Architektur,\\ + I/O-Ports in gemeinsamem Adressbereich mit Hauptspeicher,\\ + Prozessorregister und Hauptspeicher getrennt + \end{itemize} + +\end{frame} + +\subsubsection{Registerarchitekturen} + +\begin{frame}[fragile] + + \showsubsubsection + + \vspace*{-\medskipamount} + + \begin{itemize} + \item + Mehrere Register, einzeln ansprechbar + \item + \newterm{Akkumulator\/}: Nur 1 Register kann rechnen. + \item + \newterm{Stack-Architektur\/}: Stapel, "`umgekehrte Polnische Notation"' + \end{itemize} + +% \pause + + Operationen: typischerweise nur + \lstinline{=}, \lstinline{+=}, \lstinline{-=}, \lstinline{*=}, \lstinline{/=}, \dots + +% \pause + \medskip + + Beispiel: \lstinline{c = a + 2 * b;} + +% \pause + \medskip + + \begin{minipage}[t]{2cm} + C, Java:\smallskip\par + \begin{lstlisting}[gobble=6] + R = b; + R *= 2; + R += a; + c = R; + \end{lstlisting} + \end{minipage}%\pause + \begin{minipage}[t]{4cm} + Mehrere Register:\smallskip\par + \begin{lstlisting}[style=asm,gobble=6] + movl (b), %eax + imull $2, %eax, %eax + addl (a), %eax + movl %eax, (c) + \end{lstlisting} + \smallskip\par + (IA-32-Assembler) + \end{minipage}%\pause + \begin{minipage}[t]{3cm} + Akkumulator:\smallskip\par + \begin{lstlisting}[style=asm,gobble=6] + load (b) + mul $2 + add (a) + store (c) + \end{lstlisting} + \smallskip\par + (Pseudo-Assembler) + \end{minipage}%\pause + \begin{minipage}[t]{3cm} + Register-Stack:\smallskip\par + \begin{lstlisting}[style=asm,gobble=6] + push (a) + push (b) + push $2 + mul + add + pop (c) + \end{lstlisting} + \end{minipage} + +\end{frame} + +\begin{frame} + + \showsubsubsection + + Beispiele: + \begin{itemize} + \item + Intel IA-32, AMD64:\\ + Mehrere Register, für verschiedene Zwecke spezialisiert (unübersichtlich),\\[\smallskipamount] + Fließkommaregister: Stack-Architektur + \item + Atmel AVR (z.\,B.\ ATmega):\\ + 32 Register + \item + 6502, Renesas 740-CPU, Renesas-38000-Mikrocontroller:\\ + 3 Register: A, X, Y. Nur A kann rechnen $\longrightarrow$ Akkumulator + \item + Java Virtual Machine (JVM):\\ + Stack-Architektur + \item + Redcode:\\ + Jede Speicherzelle fungiert als Register + \end{itemize} + +\end{frame} + +\subsubsection{Befehlssätze} + +\begin{frame} + + \showsubsubsection + + \begin{itemize} + \item + \newterm{Reduced Instruction Set Computer (RISC)} + + \smallskip + + wenige, wenig mächtige Befehle + + \begin{onlyenv}<1> + \textarrow\ Programmierung in Assembler für Menschen unkomfortabel\\ + \textarrow\ schnelle Abarbeitung der Befehle + + \medskip + + Beispiel: Atmel AVR + \begin{itemize} + \item + Der ``load immediate''-Befehl funktioniert nur + für die Register 16 bis 31,\\ + nicht für die Register 0 bis 15. + \item + Die meisten Befehle werden in nur 1 Taktzyklus abgearbeitet. + \end{itemize} + + \medskip + + Beispiel: Redcode ICWS-86 + \begin{itemize} + \item + Es gibt indirekte Adressierung mit Prä-Dekrement,\\ + aber nicht mit Prä-Inkrement. + \item + Alle Befehle werden in nur 1 Taktzyklus abgearbeitet. + \end{itemize} + \end{onlyenv} + + \pause + \medskip + \item + \newterm{Complex Instruction Set Computer (CISC)} + + \smallskip + + Umfangreiche Befehlssätze, mächtige Befehle + + \begin{onlyenv}<2> + \textarrow\ komfortable manuelle Programmierung in Assembler\\ + \textarrow\ längere Abarbeitungszeit der einzelnen Befehle + + \smallskip + + Realisierung: "`Prozessor im Prozessor"' -- \newterm{Mikroprogramme} + + \medskip + + Beispiel: Intel IA-32, AMD64 + \begin{itemize} + \item + Es gibt spezielle Befehle für BCD- und String-Operationen. + \item + Befehle benötigen meistens 2 oder mehr,\\ + gelegentlich (z.\,B.\ Fließkomma-Operationen) auch über 100 Taktzyklen. + \end{itemize} + \end{onlyenv} + + \medskip + \pause + \item + \newterm{Very Long Instruction Word (VLIW)\/} und\\ + \newterm{Explicitly Parallel Instruction Computing (EPIC)} + + \smallskip + + mehrere Befehle gleichzeitig ausführbar + + \begin{onlyenv}<3> + \textarrow\ mehr Rechenleistung möglich\\ + \textarrow\ Programmierung sehr aufwendig + + \medskip + + Beispiel: Intel IA-64 + \end{onlyenv} + + \pause + \medskip + \item + \newterm{Orthogonaler Befehlssatz} + + \smallskip + + Jeder Befehl ist mit jeder Adressierungsart kombinierbar. + + \medskip + + Beispiel: Redcode + \end{itemize} + \vspace*{-4cm} + +\end{frame} + +\subsection{Der CPU-Stack\label{CPU-Stack}} +\addtocounter{subsubsection}{-1} +\subsubsection{Was ist ein Stack?} + +\begin{frame}[fragile] + + \showsubsection + \showsubsubsection + + \bigskip + +\iffalse + + \begin{minipage}[b]{6cm} + \begin{center} + "`First In -- First Out"' + + \bigskip + + \begin{picture}(6,4) + \thicklines + \color{structure} + \put(0.5,0){\line(1,0){5}} + + \put(3.5,0){\only<1-5>{\line(0,1){1}}} + \put(4.5,0){\only<1-4>{\line(0,1){1}}} + \put(3.5,1){\only<1-4>{\line(1,0){1}}} + \put(4.0,0.5){\only<1-4>{\makebox(0,0){\lstinline{3}}}} + \put(3.0,1.5){\only<1>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(3.0,1.5){\only<1>{\makebox(0,0)[b]{\lstinline{push (3)}}}} + + \put(2.5,0){\only<2-6>{\line(0,1){1}}} + \put(2.5,1){\only<2-5>{\line(1,0){1}}} + \put(3.0,0.5){\only<2-5>{\makebox(0,0){\lstinline{7}}}} + \put(2.0,1.5){\only<2>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(2.0,1.5){\only<2>{\makebox(0,0)[b]{\lstinline{push (7)}}}} + + \put(1.5,0){\only<3-6>{\line(0,1){1}}} + \put(1.5,1){\only<3-6>{\line(1,0){1}}} + \put(2.0,0.5){\only<3-6>{\makebox(0,0){\lstinline{137}}}} + \put(1.0,1.5){\only<3>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(1.0,1.5){\only<3>{\makebox(0,0)[b]{\lstinline{push (137)}}}} + + \put(4.55,1.05){\only<4>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(5.00,1.60){\only<4>{\makebox(0,0)[b]{\lstinline{pop ()}: 3}}} + + \put(3.55,1.05){\only<5>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(4.00,1.60){\only<5>{\makebox(0,0)[b]{\lstinline{pop ()}: 7}}} + + \put(2.55,1.05){\only<6>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(3.00,1.60){\only<6>{\makebox(0,0)[b]{\lstinline{pop ()}: 137}}} + \end{picture} + + \bigskip + + FIFO = Queue = Reihe + \end{center} + \end{minipage}\hfill + +\fi + + \begin{minipage}[b]{6cm} + \begin{center} + "`Last In -- First Out"' + + \bigskip + + \begin{picture}(6,4) + \thicklines + \color{structure} + \put(1.5,0){\line(1,0){3}} + + \put(2.5,0){\line(0,1){1}} + \put(3.5,0){\line(0,1){1}} + \put(2.5,1){\line(1,0){1}} + \put(3.0,0.5){\makebox(0,0){\lstinline{3}}} + \put(2.0,1.5){\only<1>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(2.0,1.5){\only<1>{\makebox(0,0)[b]{\lstinline{push (3)}}}} + + \put(2.5,1){\only<2-5>{\line(0,1){1}}} + \put(3.5,1){\only<2-5>{\line(0,1){1}}} + \put(2.5,2){\only<2-5>{\line(1,0){1}}} + \put(3.0,1.5){\only<2-5>{\makebox(0,0){\lstinline{7}}}} + \put(2.0,2.5){\only<2>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(2.0,2.5){\only<2>{\makebox(0,0)[b]{\lstinline{push (7)}}}} + + \put(2.5,2){\only<3-4>{\line(0,1){1}}} + \put(3.5,2){\only<3-4>{\line(0,1){1}}} + \put(2.5,3){\only<3-4>{\line(1,0){1}}} + \put(3.0,2.5){\only<3-4>{\makebox(0,0){\lstinline{137}}}} + \put(2.0,3.5){\only<3>{\makebox(0,0)[tl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,-0.45);}}}} + \put(2.0,3.5){\only<3>{\makebox(0,0)[b]{\lstinline{push (137)}}}} + + \put(3.55,3.05){\only<4>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(4.00,3.60){\only<4>{\makebox(0,0)[b]{\lstinline{pop ()}: 137}}} + + \put(3.55,2.05){\only<5>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(4.00,2.60){\only<5>{\makebox(0,0)[b]{\lstinline{pop ()}: 7}}} + + \put(3.55,1.05){\only<6>{\makebox(0,0)[bl]{\tikz{\draw[-latex, line width=1pt](0,0)--(0.45,0.45);}}}} + \put(4.00,1.60){\only<6>{\makebox(0,0)[b]{\lstinline{pop ()}: 3}}} + \end{picture} + + \bigskip + + LIFO = Stack = Stapel + \end{center} + \end{minipage} + +% +% \dots + +\end{frame} +\subsubsection{Implementierung} + +\begin{frame} + + \showsubsection + \showsubsubsection + + Speicher, in dem Werte "`gestapelt"' werden: \newterm{Stack} + + \begin{itemize} + \item + Speicherbereich (ein array) reservieren + \item + Variable (typischerweise: Prozessorregister) als + \newterm{Stack Pointer\/} reservieren \textarrow\ \lstinline{SP} + \item + Assembler-Befehl \lstinline[style=asm]{push foo}: \quad + \lstinline{*SP++ = foo;} + \begin{itemize} + \item + In der Speicherzelle, + auf die der Stack Pointer \lstinline{SP} gerade zeigt,\\ + den Wert \lstinline{foo} speichern. + \item + Danach den Stack Pointer inkrementieren (um 1 erhöhen). + \end{itemize} + \item + Assembler-Befehl \lstinline[style=asm]{pop bar}: \quad + \lstinline{bar = *--SP;} + \begin{itemize} + \item + Zuerst den Stack Pointer dekrementieren (um 1 erniedrigen). + \item + Danach aus der Speicherzelle,\\ + auf die der Stack Pointer \lstinline{SP} gerade zeigt,\\ + einen Wert lesen und in der Variablen \lstinline{bar} speichern. + \end{itemize} + \end{itemize} + +% \pause + \medskip + Speziell: Unterprogramme + +\end{frame} + +\subsubsection{Unterprogramme} + +\begin{frame}[fragile] + + \showsubsection + \showsubsubsection + + Funktion mit 2 ganzzahligen Parametern \lstinline{a} und \lstinline{b}\\ + und einem ganzzahligem Rückgabewert: + \vspace{\medskipamount} + \begin{lstlisting}[xleftmargin=1em] + int sum (int a, int b) + { + return a + b; + } + \end{lstlisting} + + \bigskip + + Aufruf der Funktion: + \vspace{\medskipamount} + \begin{lstlisting}[xleftmargin=1em] + int c = sum (7, 6); + \end{lstlisting} + + \bigskip + + (Methoden = spezielle Funktionen) + + \vfill + + \textarrow\ Wie funktioniert das? + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + \showsubsubsection + + \begin{minipage}[t]{5.5cm} + Parameter: + \begin{itemize} + \item + Prozessorregister + \item + CPU-Stack + \end{itemize} + + \smallskip + + Rückgabewert: + \begin{itemize} + \item + Prozessorregister + \end{itemize} + \end{minipage}% + \begin{minipage}[t]{5cm} + Aufruf: + \begin{itemize} + \item + \lstinline[style=asm]{push IP}\\ + \lstinline[style=asm]{jmp foo} + {\color{red}\boldmath $\longleftarrow$ mov \#foo IP}\\ + \textarrow\ \lstinline[style=asm]{call foo} + \end{itemize} + Rücksprung: + \begin{itemize} + \item + \lstinline[style=asm]{pop IP}\\ + \textarrow\ \lstinline[style=asm]{ret} + \end{itemize} + \end{minipage} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + \showsubsubsection + + \begin{minipage}[t]{5.5cm} + Parameter: + \begin{itemize} + \item + Prozessorregister + \item + CPU-Stack + \end{itemize} + + \smallskip + + Rückgabewert: + \begin{itemize} + \item + Prozessorregister + \end{itemize} + \end{minipage}% + \begin{minipage}[t]{5cm} + Aufruf: + \begin{itemize} + \item + \lstinline[style=asm]{push IP}\\ + \lstinline[style=asm]{jmp foo} + {\color{red}\boldmath $\longleftarrow$ mov \#foo IP}\\ + \textarrow\ \lstinline[style=asm]{call foo} + \end{itemize} + Rücksprung: + \begin{itemize} + \item + \lstinline[style=asm]{pop IP}\\ + \textarrow\ \lstinline[style=asm]{ret} + \end{itemize} + \end{minipage} + + \bigskip + + \subsubsection{Lokale Variable} + \showsubsubsection + + \dots\ speichert man oft ebenfalls auf dem Stack. + + \smallskip + + Speicherplatz reservieren: Stack-Pointer modifizieren + + \medskip + + \newterm{Buffer Overflow\/}:\\[0.5\smallskipamount] + Über die Grenzen einer lokalen Variablen hinausschreiben,\\ + dabei Rücksprungadresse überschreiben \textarrow\ Absturz + +\end{frame} + +\subsubsection{Register sichern} + +\begin{frame} + + \showsubsection + \showsubsubsection + + Ein Unterprogramm verändert Registerinhalte. + \begin{itemize} + \item + im Hauptprogramm nötigenfalls vor Aufruf sichern + \item + im Unterprogramm vor Benutzung sichern + \item + Kombinationen (manche Register so, manche so) + \end{itemize} + +\end{frame} + +\subsection{Computer-Sprachen} +\subsubsection{Maschinensprache} + +\iffalse + +\begin{frame} + + \showsubsection + \showsubsubsection + + \strut\hfill + \begin{minipage}{6.5cm} + \vspace*{-1.7cm} + \small + Computer + \begin{itemize}\itemsep0pt + \item Rechenwerk (ALU) + \item Speicher: Register,\\ + adressierbarer Hauptspeicher + \item Takt: Befehle abarbeiten + \item Peripherie: Kommunikation\\ + mit der Außenwelt + \arrowitem in Maschinensprache programmierbar + \end{itemize} + \end{minipage}\hspace*{-0.5cm} + + In jedem Takt: + \begin{itemize} + \item + dort aus dem Hauptspeicher lesen, wohin das Register \lstinline{IP} zeigt\\ + \textarrow\ \newterm{Befehl\/} (\newterm{Instruction\/} -- \lstinline{IP} = \newterm{Instruction Pointer\/}) + \item + den \newterm{Befehl\/} an den \newterm{Funktion\/}-Eingang der \newterm{ALU\/} legen + \item + auf ähnliche Weise weitere Daten an den \newterm{Akkumulator\/}-\\ + und den \newterm{Daten\/}-Eingang der \newterm{ALU\/} legen + \item + auf ähnliche Weise den \newterm{Ergebnis\/}-Ausgang der \newterm{ALU}\\ + in den Hauptspeicher schreiben + \textarrow\ Befehl ausgeführt + \item + Register \lstinline{IP} hochzählen + \textarrow\ nächster Befehl + \arrowitem + Maschinensprache + \end{itemize} + +\end{frame} + +\fi + +\begin{frame} + + \showsubsection + \showsubsubsection + + \begin{itemize} + \item + Lade- und Speicher-Befehle\\ + arithmetische Befehle\\ + unbedingte und bedingte Sprungbefehle + \arrowitem + Der Computer kann "`alles"' -- \newterm{Turing-Vollständigkeit} + \bigskip + \item + Maschinensprache = Zahlen \textarrow\ für Menschen schwer handhabbar + \arrowitem + Namen für die Befehle: \newterm{Mnemonics} + \arrowitem + \newterm{Assembler\/}-Sprache + \end{itemize} + +\end{frame} + +\subsubsection{\strut{\protect\color{gray}Maschinensprache \protect\textarrow\ }Assembler} + +\begin{frame}[fragile] + + \showsubsubsection + + Beispiel: Intel-x86-16-Bit-Assembler + + \begin{itemize} + \item + Lade- und Speicher-Befehle\hfill + \lstinline{mov}, \dots\\ + arithmetische Befehle\hfill + \lstinline{add}, \lstinline{sub}, \lstinline{inc}, \lstinline{dec}, + \lstinline{xor}, \lstinline{cmp}, \dots\\ + unbedingte und bedingte Sprungbefehle\hfill + \lstinline{jmp}, \lstinline{jz}, \lstinline{jae}, \dots + \item + Register\hfill + \lstinline{ax}, \lstinline{bx}, \dots + \end{itemize} + +% \begin{onlyenv}<1> +% \begin{center} +%% \includegraphics[width=10cm]{programm-screenshot.png} +% \vspace*{-0.5cm} +% \end{center} +% \end{onlyenv} +% \begin{onlyenv}<2-> + + \bigskip + + Beispiel: Atmel-AVR-8-Bit-Assembler + + \begin{itemize} + \item + Lade- und Speicher-Befehle\hfill + \lstinline{ldi}, \lstinline{lds}, \lstinline{sti}, \dots\\ + arithmetische Befehle\hfill + \lstinline{add}, \lstinline{sub}, \lstinline{subi}, + \lstinline{eor}, \lstinline{cp}, \dots\\ + unbedingte und bedingte Sprungbefehle\hfill + \lstinline{rjmp}, \lstinline{brsh}, \lstinline{brlo}, \dots + \item + Register\hfill + \lstinline{r0}, \lstinline{r1}, \dots + \end{itemize} + + \bigskip + + \textarrow\ für jeden Prozessor anders + +% \end{onlyenv} + +\end{frame} + +\subsubsection{\strut{\protect\color{gray}Maschinensprache \protect\textarrow\ Assembler \protect\textarrow\ }Hochsprachen} + +\begin{frame}[fragile] + + \showsubsubsection + + Beispiel: Intel-x86-16-Bit-Assembler + + \begin{itemize} + \item + Lade- und Speicher-Befehle\hfill + \lstinline{mov}, \dots\\ + arithmetische Befehle\hfill + \lstinline{add}, \lstinline{sub}, \lstinline{inc}, \lstinline{dec}, + \lstinline{xor}, \lstinline{cmp}, \dots\\ + unbedingte und bedingte Sprungbefehle\hfill + \lstinline{jmp}, \lstinline{jz}, \lstinline{jae}, \dots + \item + Register\hfill + \lstinline{ax}, \lstinline{bx}, \dots + \end{itemize} + + \bigskip + + Beispiel: Atmel-AVR-8-Bit-Assembler + + \begin{itemize} + \item + Lade- und Speicher-Befehle\hfill + \lstinline{ldi}, \lstinline{lds}, \lstinline{sti}, \dots\\ + arithmetische Befehle\hfill + \lstinline{add}, \lstinline{sub}, \lstinline{subi}, + \lstinline{eor}, \lstinline{cp}, \dots\\ + unbedingte und bedingte Sprungbefehle\hfill + \lstinline{rjmp}, \lstinline{brsh}, \lstinline{brlo}, \dots + \item + Register\hfill + \lstinline{r0}, \lstinline{r1}, \dots + \end{itemize} + + \bigskip + + \textarrow\ für jeden Prozessor anders + + \bigskip + + Hochsprache \textarrow\ für jeden Prozessor gleich + +\end{frame} + +\begin{frame}[fragile] + + \showsubsubsection + + Compiler-Sprachen + \begin{itemize} + \item + \newterm{Compiler\/} übersetzt Hochsprachen-\newterm{Quelltext\/} in die Assembler-Sprache + \item + \newterm{Assembler\/} übersetzt Assembler-Quelltext in die Maschinensprache + \item + Compiler und Assembler sind Programme,\\ + geschrieben in Maschinensprache, Assembler oder einer Hochsprache + \item + Beispiele: Fortran, Algol, Pascal, Ada, C, C++, \dots + \end{itemize} + + \pause + \medskip + Interpreter- oder Skript-Sprachen + \begin{itemize} + \item + \newterm{Interpreter\/} liest Hochsprachen-\newterm{Quelltext\/} und führt ihn sofort aus + \item + Der Interpreter ist ein Programm,\\ + geschrieben in Maschinensprache, Assembler oder einer Hochsprache + \item + Beispiele: Unix-Shell, BASIC, Perl, Python, \dots + \end{itemize} + + \pause + \medskip + Kombinationen + \begin{itemize} + \item + \newterm{Compiler\/} erzeugt \newterm{Zwischencode\/} für eine \newterm{virtuelle Maschine} + \item + \newterm{Interpreter\/} liest Hochsprachen-\newterm{Zwischencode\/} und führt ihn sofort aus + \item + Die virtuelle Maschine ist ein Programm, + geschrieben in Maschinensprache, Assembler, einer Hoch- oder Skript-Sprache + \item + Beispiele: UCSD-Pascal, Java, \dots + \end{itemize} + \medskip + +\end{frame} + +\section{Hardwarenahe Programmierung} +\subsection{Bit-Operationen} +\subsubsection{Zahlensysteme} + +\begin{frame}[fragile] + + \showsection + \vspace*{-\smallskipamount} + \showsubsection + \vspace*{-\medskipamount} + \showsubsubsection + + \begin{tabular}{rlrl} + Basis & Name & Beispiel & Anwendung \\[\smallskipamount] + 2 & Binärsystem & 1\,0000\,0011 & Bit-Operationen \\ + 8 & Oktalsystem & \lstinline,0403, & Dateizugriffsrechte (Unix) \\ + 10 & Dezimalsystem & \lstinline,259, & Alltag \\ + 16 & Hexadezimalsystem & \lstinline,0x103, & Bit-Operationen \\ + 256 & (keiner gebräuchlich) & 0.0.1.3 & IP-Adressen (IPv4) + \end{tabular} + + \bigskip + + \begin{itemize} + \item + Computer rechnen im Binärsystem. + \item + Für viele Anwendungen (z.\,B.\ I/O-Ports, Grafik, \dots) ist es notwendig,\\ + Bits in Zahlen einzeln ansprechen zu können. + \end{itemize} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsubsection + + \begin{tabular}{rlrlrc} + \qquad 000 & \bf 0 \hspace*{1.5cm} & 0000 & \bf 0 & \quad 1000 & \bf 8\\ + 001 & \bf 1 & 0001 & \bf 1 & 1001 & \bf 9\\ + 010 & \bf 2 & 0010 & \bf 2 & 1010 & \bf A\\ + 011 & \bf 3 & 0011 & \bf 3 & 1011 & \bf B\\[\smallskipamount] + 100 & \bf 4 & 0100 & \bf 4 & 1100 & \bf C\\ + 101 & \bf 5 & 0101 & \bf 5 & 1101 & \bf D\\ + 110 & \bf 6 & 0110 & \bf 6 & 1110 & \bf E\\ + 111 & \bf 7 & 0111 & \bf 7 & 1111 & \bf F\\ + \end{tabular} + + \medskip + + \begin{itemize} + \item + Oktal- und Hexadezimalzahlen lassen sich ziffernweise\\ + in Binär-Zahlen umrechnen. + \item + Hexadezimalzahlen sind eine Kurzschreibweise für Binärzahlen,\\ + gruppiert zu jeweils 4 Bits. + \item + Oktalzahlen sind eine Kurzschreibweise für Binärzahlen,\\ + gruppiert zu jeweils 3 Bits. + \item + Trotz Taschenrechner u.\,ä.\ lohnt es sich,\\ + die o.\,a.\ Umrechnungstabelle \textbf{auswendig} zu kennen. + \end{itemize} + +\end{frame} + +\subsubsection{Bit-Operationen in Assembler} + +\begin{frame}[fragile] + + \showsubsubsection + + \begin{tabular}{lll} + Operation & Verknüpfung & Anwendung \\[\smallskipamount] + \lstinline,and, & Und & Bits gezielt löschen \\ + \lstinline,or, & Oder & Bits gezielt setzen \\ + \lstinline,eor, & Exklusiv-Oder & Bits gezielt invertieren \\[\smallskipamount] + \lstinline,com, & Nicht (Einer-Komplement) & Alle Bits invertieren \\[\smallskipamount] + \lstinline,lsl, & Verschiebung nach links & Maske generieren \\ +% \lstinline,lsr, & Verschiebung nach rechts & Bits isolieren + \end{tabular} + + \bigskip + + Numerierung der Bits: von rechts ab 0 + + \medskip + + \begin{tabular}{ll} + Bit Nr.\ 3 auf 1 setzen: & +% \lstinline,a |= 1 << 3;, \\ + Oder-Verknüpfung mit einer\\&um 3 nach links geschobenen 1 + \hfill\lstinline|0000|\,\lstinline|1000|\\[\smallskipamount] + Bit Nr.\ 4 auf 0 setzen: & +% \lstinline,a &= ~(1 << 4);, \\ + Und-Verknüpfung mit dem Einer-Komplement \qquad\quad\strut\\&einer um 4 nach links geschobenen 1 + \hfill\lstinline|1110|\,\lstinline|1111|\\[\smallskipamount] + Bit Nr.\ 0 invertieren: & +% \lstinline,a ^= 1 << 0;, + Exklusiv-Oder-Verknüpfung mit einer\\&um 0 nach links geschobenen 1 + \hfill\lstinline|0000|\,\lstinline|0001|\\[\smallskipamount] + Ist Bit Nr.\ 1 eine Null? & + Ergibt eine Und-Verknüpfung mit einer um 1\\&nach links geschobenen 1 den Wert 0? + \hfill\lstinline|0000|\,\lstinline|0010| + \end{tabular} + +% \smallskip +% +% ~~Abfrage, ob Bit Nr.\ 1 gesetzt ist:\quad +% \lstinline{if (a & (1 << 1))} + +\end{frame} + +\iffalse + +\begin{frame}[fragile] + + \showsubsubsection + + C-Datentypen für Bit-Operationen: + \smallskip\par + \lstinline{#include <stdint.h>} + \medskip\par + \begin{tabular}{lllll} + & 8 Bit & 16 Bit & 32 Bit & 64 Bit \\ + mit Vorzeichen & \lstinline,int8_t, + & \lstinline,int16_t, + & \lstinline,int32_t, + & \lstinline,int64_t, \\ + ohne Vorzeichen & \lstinline,uint8_t, + & \lstinline,uint16_t, + & \lstinline,uint32_t, + & \lstinline,uint64_t, + \end{tabular} + + \bigskip + \bigskip + + Ausgabe: + \smallskip\par + \begin{lstlisting} + #include <stdio.h> + #include <stdint.h> + #include <inttypes.h> + ... + uint64_t x = 42; + printf ("Die Antwort lautet: %" PRIu64 "\n", x); + \end{lstlisting} + +\end{frame} + +\subsection{I/O-Ports} + +\begin{frame}[fragile] + +% \showsection + \showsubsection + \vspace*{-1.5\medskipamount} + {\large\textbf{\color{structure}4.3\quad Interrupts}} + + \bigskip + + Kommunikation mit externen Geräten + + \bigskip + + \begin{center} + \includegraphics{io-ports-and-interrupts.pdf} + \end{center} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + In Output-Port schreiben = Aktoren ansteuern + + Beispiel: LED + + \medskip + + \begin{lstlisting} + #include <avr/io.h> + ... + DDRC = 0x70; + PORTC = 0x40; + \end{lstlisting} + \begin{picture}(0,0) + \put(3,0.67){\begin{minipage}{3cm} + \color{red}% + binär: 0111\,0000\\ + binär: 0100\,0000 + \end{minipage}} + \put(10,0.67){\makebox(0,0)[r]{\color{red}Herstellerspezifisch!}} + \end{picture} + + \bigskip + + \lstinline{DDR} = Data Direction Register\\ + Bit = 1 für Output-Port\\ + Bit = 0 für Input-Port + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Aus Input-Port lesen = Sensoren abfragen + + Beispiel: Taster + + \medskip + + \begin{lstlisting} + #include <avr/io.h> + ... + DDRC = 0xfd; + while ((PINC & 0x02) == 0) + ; /* just wait */ + \end{lstlisting} + \begin{picture}(0,0)(-1.5,-0.42) + \put(3,0.67){\begin{minipage}{3cm} + \color{red}% + binär: 1111\,1101\\ + binär: 0000\,0010 + \end{minipage}} + \put(10,0.67){\makebox(0,0)[r]{\color{red}Herstellerspezifisch!}} + \end{picture} + + \bigskip + + \lstinline{DDR} = Data Direction Register\\ + Bit = 1 für Output-Port\\ + Bit = 0 für Input-Port + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + + \bigskip + + Praktikumsaufgabe: Druckknopfampel + +\end{frame} + +\subsection{Interrupts} + +\begin{frame}[fragile] + + \showsubsection + + Externes Gerät ruft (per Stromsignal) Unterprogramm auf + + Zeiger hinterlegen: "`Interrupt-Vektor"' + + Beispiel: eingebaute Uhr\hfill + \makebox(0,0)[tr]{% + \only<1->{\begin{minipage}[t]{4.7cm} + \vspace*{-0.3cm}% + statt Zählschleife (\lstinline{_delay_ms}):\\ + Hauptprogramm kann\\ + andere Dinge tun + \end{minipage}}% + } + + \medskip + + \begin{lstlisting} + #include <avr/interrupt.h> + + ... + + + ISR (TIMER0B_COMP_vect) + { + PORTD ^= 0x40; + } + \end{lstlisting} + \begin{picture}(0,0) + \color{red} + \put(1.9,3.1){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-1.4,-1.0);}}} + \put(2.0,3.2){\makebox(0,0)[l]{"`Dies ist ein Interrupt-Handler."'}} + \put(2.3,2.6){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-0.6,-0.55);}}} + \put(2.4,2.6){\makebox(0,0)[l]{Interrupt-Vektor darauf zeigen lassen}} + \end{picture} + + Initialisierung über spezielle Ports: + \lstinline{TCCR0B}, \lstinline{TIMSK0} + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + + \vspace*{-2.5cm}\hfill + {\color{red}Herstellerspezifisch!}% + \hspace*{1cm} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Externes Gerät ruft (per Stromsignal) Unterprogramm auf + + Zeiger hinterlegen: "`Interrupt-Vektor"' + + Beispiel: Taster\hfill + \makebox(0,0)[tr]{% + \begin{minipage}[t]{4.7cm} + \vspace*{-0.3cm}% + statt \newterm{Busy Waiting\/}:\\ + Hauptprogramm kann\\ + andere Dinge tun + \end{minipage}} + + \medskip + + \begin{lstlisting} + #include <avr/interrupt.h> + ... + + ISR (INT0_vect) + { + PORTD ^= 0x40; + } + \end{lstlisting} + + \medskip + + Initialisierung über spezielle Ports: + \lstinline{EICRA}, \lstinline{EIMSK} + + \bigskip + + \emph{Details: siehe Datenblatt und Schaltplan} + + \vspace*{-2.5cm}\hfill + {\color{red}Herstellerspezifisch!}% + \hspace*{1cm} + +\end{frame} + +\subsection{volatile-Variable} + +\begin{frame}[fragile] + + \showsubsection + + Externes Gerät ruft (per Stromsignal) Unterprogramm auf + + Zeiger hinterlegen: "`Interrupt-Vektor"' + + Beispiel: Taster + + \vspace*{-2.5pt} + + \begin{minipage}[t]{5cm} + \begin{onlyenv}<1> + \begin{lstlisting}[gobble=8] + ¡#include <avr/interrupt.h> + ... + + uint8_t key_pressed = 0; + + ISR (INT0_vect) + { + key_pressed = 1; + }¿ + \end{lstlisting} + \end{onlyenv} + \begin{onlyenv}<2> + \begin{lstlisting}[gobble=8] + ¡#include <avr/interrupt.h> + ... + + volatile uint8_t key_pressed = 0; + + ISR (INT0_vect) + { + key_pressed = 1; + }¿ + \end{lstlisting} + \end{onlyenv} + \end{minipage}\hfill + \begin{minipage}[t]{6cm} + \begin{lstlisting}[gobble=6] + ¡int main (void) + { + ... + + while (1) + { + while (!key_pressed) + ; /* just wait */ + PORTD ^= 0x40; + key_pressed = 0; + } + return 0; + }¿ + \end{lstlisting} + \end{minipage} + + \pause + \begin{picture}(0,0) + \color{red} + \put(10.3,4.0){\makebox(0,0)[b]{\begin{minipage}{6cm} + \begin{center} + \textbf{volatile}:\\ + Speicherzugriff\\ + nicht wegoptimieren + \end{center} + \end{minipage}}} + \put(10.3,3.95){\makebox(0,0)[tr]{\tikz{\draw[-latex](0,0)--(-0.5,-0.9);}}} + \end{picture} + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Was ist eigentlich \lstinline{PORTD}? + + \bigskip + \pause + + \lstinline[style=cmd]{avr-gcc -Wall -Os -mmcu=atmega328p blink-3.c -E} + + \bigskip + \pause + \lstinline{PORTD = 0x01;}\\ + \textarrow\quad + \lstinline[style=terminal]{(*(volatile uint8_t *)((0x0B) + 0x20)) = 0x01;}\\ + \pause + \begin{picture}(0,2)(0,-1.7) + \color{red} + \put(5.75,0.3){$\underbrace{\rule{2.95cm}{0pt}}_{\mbox{Zahl: \lstinline|0x2B|}}$} + \pause + \put(1.55,0.3){$\underbrace{\rule{4.0cm}{0pt}}_{\mbox{\shortstack[t]{Umwandlung in Zeiger\\ + auf \lstinline|volatile uint8_t|}}}$} + \pause + \put(1.32,-1){\makebox(0,0)[b]{\tikz{\draw[-latex](0,0)--(0,1.3)}}} + \put(1.12,-1.1){\makebox(0,0)[tl]{Dereferenzierung des Zeigers}} + \end{picture} + + \pause + \textarrow\quad + \lstinline|volatile uint8_t|-Variable an Speicheradresse \lstinline|0x2B| + + \pause + \bigskip + \bigskip + + \textarrow\quad + \lstinline|PORTA = PORTB = PORTC = PORTD = 0| ist eine schlechte Idee. + +\end{frame} + +\subsection{Byte-Reihenfolge -- Endianness} +\subsubsection{Konzept} + +\begin{frame}[fragile] + + \showsubsection + \showsubsubsection + + Eine Zahl geht über mehrere Speicherzellen.\\ + Beispiel: 16-Bit-Zahl in 2 8-Bit-Speicherzellen + + \smallskip + + Welche Bits liegen wo? + +% \pause + \bigskip + + $1027 = 1024 + 2 + 1 = 0000\,0100\,0000\,0011_2 = 0403_{16}$ + +% \pause + \bigskip + Speicherzellen: + + \medskip + \begin{tabular}{|c|c|l}\cline{1-2} + \raisebox{-0.25ex}{04} & \raisebox{-0.25ex}{03} & \strut Big-Endian "`großes Ende zuerst"' \\\cline{1-2} + \multicolumn{2}{c}{} & % \pause + für Menschen leichter lesbar % \pause + \\ + \multicolumn{3}{c}{} \\[-5pt]\cline{1-2} + \raisebox{-0.25ex}{03} & \raisebox{-0.25ex}{04} & \strut Little-Endian "`kleines Ende zuerst"' \\\cline{1-2} + \multicolumn{2}{c}{} & % \pause + bei Additionen effizienter + \end{tabular} + +% \pause + \medskip + \textarrow\ Geschmackssache +% \pause\\ + \quad\textbf{\dots\ außer bei Datenaustausch!} + +% \pause +% \bigskip +% +% Aber: nicht verwechseln! \qquad $0304_{16} = 772$ + +\end{frame} + +\begin{frame} + + \showsubsection + \showsubsubsection + + Eine Zahl geht über mehrere Speicherzellen.\\ + Beispiel: 16-Bit-Zahl in 2 8-Bit-Speicherzellen + + \smallskip + + Welche Bits liegen wo? + + \medskip + + \textarrow\ Geschmackssache\\ + \textbf{\dots\ außer bei Datenaustausch!} + + \begin{itemize} + \item + Dateiformate + \item + Datenübertragung + \end{itemize} + +\end{frame} + +\subsubsection{Dateiformate} + +\begin{frame} + + \showsubsection + \showsubsubsection + + Audio-Formate: Reihenfolge der Bytes in 16- und 32-Bit-Zahlen + \begin{itemize} + \item + RIFF-WAVE-Dateien (\file{.wav}): Little-Endian + \item + Au-Dateien (\file{.au}): Big-Endian +% \pause + \item + ältere AIFF-Dateien (\file{.aiff}): Big-Endian + \item + neuere AIFF-Dateien (\file{.aiff}): Little-Endian + \end{itemize} + +% \pause + \bigskip + + Grafik-Formate: Reihenfolge der Bits in den Bytes + \begin{itemize} + \item + PBM-Dateien: Big-Endian\only<1->{, MSB first} + \item + XBM-Dateien: Little-Endian\only<1->{, LSB first} + \end{itemize} + \only<1->{MSB/LSB = most/least significant bit} + +\end{frame} + +\subsubsection{Datenübertragung} + +\begin{frame} + + \showsubsection + \showsubsubsection + + \begin{itemize} + \item + RS-232 (serielle Schnittstelle): LSB first + \item + I$^2$C: MSB first + \item + USB: beides + \pause + \medskip + \item + Ethernet: LSB first + \item + TCP/IP (Internet): Big-Endian + \end{itemize} + +\end{frame} + +\iffalse + +\subsection{Binärdarstellung negativer Zahlen} + +\begin{frame}[fragile] + + \showsubsection + + Speicher ist begrenzt!\\ + \textarrow\ feste Anzahl von Bits + + \medskip + + 8-Bit-Zahlen ohne Vorzeichen: \lstinline{uint8_t}\\ + \textarrow\ Zahlenwerte von \lstinline{0x00} bis \lstinline{0xff} = 0 bis 255\\ + \pause + \textarrow\ 255 + 1 = 0 + + \pause + \medskip + + 8-Bit-Zahlen mit Vorzeichen: \lstinline{int8_t}\\ + \lstinline{0xff} = 255 ist die "`natürliche"' Schreibweise für $-1$.\\ + \pause + \textarrow\ Zweierkomplement + + \pause + \medskip + + Oberstes Bit = 1: negativ\\ + Oberstes Bit = 0: positiv\\ + \textarrow\ 127 + 1 = $-128$ + +\end{frame} + +\begin{frame}[fragile] + + \showsubsection + + Speicher ist begrenzt!\\ + \textarrow\ feste Anzahl von Bits + + \medskip + + 16-Bit-Zahlen ohne Vorzeichen: + \lstinline{uint16_t}\hfill\lstinline{uint8_t}\\ + \textarrow\ Zahlenwerte von \lstinline{0x0000} bis \lstinline{0xffff} + = 0 bis 65535\hfill 0 bis 255\\ + \textarrow\ 65535 + 1 = 0\hfill 255 + 1 = 0 + + \medskip + + 16-Bit-Zahlen mit Vorzeichen: + \lstinline{int16_t}\hfill\lstinline{int8_t}\\ + \lstinline{0xffff} = 66535 ist die "`natürliche"' Schreibweise für $-1$.\hfill + \lstinline{0xff} = 255 = $-1$\\ + \textarrow\ Zweierkomplement + + \medskip + + Oberstes Bit = 1: negativ\\ + Oberstes Bit = 0: positiv\\ + \textarrow\ 32767 + 1 = $-32768$ + + \bigskip + Literatur: \url{http://xkcd.com/571/} + +\end{frame} + +\fi + +\begin{frame}[fragile] + + \showsubsection + + Frage: \emph{Für welche Zahl steht der Speicherinhalt\, + \raisebox{2pt}{% + \tabcolsep0.25em + \begin{tabular}{|c|c|}\hline + \rule{0pt}{11pt}a3 & 90 \\\hline + \end{tabular}} + (hexadezimal)?} + + \pause + \smallskip + Antwort: \emph{Das kommt darauf an.} ;--) + + \pause + \medskip + Little-Endian: + + \smallskip + + \begin{tabular}{lrl} + als \lstinline,int8_t,: & $-93$ & (nur erstes Byte)\\ + als \lstinline,uint8_t,: & $163$ & (nur erstes Byte)\\ + als \lstinline,int16_t,: & $-28509$\\ + als \lstinline,uint16_t,: & $37027$\\ + \lstinline,int32_t, oder größer: & $37027$ + & (zusätzliche Bytes mit Nullen aufgefüllt) + \end{tabular} + + \pause + \medskip + Big-Endian: + + \smallskip + + \begin{tabular}{lrl} + als \lstinline,int8_t,: & $-93$ & (nur erstes Byte)\\ + als \lstinline,uint8_t,: & $163$ & (nur erstes Byte)\\ + als \lstinline,int16_t,: & $-23664$\\ + als \lstinline,uint16_t,: & $41872$\\ als \lstinline,int32_t,: & $-1550843904$ & (zusätzliche Bytes\\ + als \lstinline,uint32_t,: & $2744123392$ & mit Nullen aufgefüllt)\\ + als \lstinline,int64_t,: & $-6660823848880963584$\\ + als \lstinline,uint64_t,: & $11785920224828588032$\\ + \end{tabular} + + \vspace*{-1cm} + +\end{frame} + +\subsection{Speicherausrichtung -- Alignment} + +\begin{frame}[fragile] + + \showsubsection + + \begin{lstlisting} + #include <stdint.h> + + uint8_t a; + uint16_t b; + uint8_t c; + \end{lstlisting} + + \pause + \bigskip + + Speicheradresse durch 2 teilbar -- "`16-Bit-Alignment"' + \begin{itemize} + \item + 2-Byte-Operation: effizienter + \pause + \item + \dots\ oder sogar nur dann erlaubt + \pause + \arrowitem + Compiler optimiert Speicherausrichtung + \end{itemize} + + \medskip + + \pause + \begin{minipage}{3cm} + \begin{lstlisting}[gobble=6] + ¡uint8_t a; + uint8_t dummy; + uint16_t b; + uint8_t c;¿ + \end{lstlisting} + \end{minipage} + \pause + \begin{minipage}{3cm} + \begin{lstlisting}[gobble=6] + ¡uint8_t a; + uint8_t c; + uint16_t b;¿ + \end{lstlisting} + \end{minipage} + + \pause + \vspace{-1.75cm} + \strut\hfill + \begin{minipage}{6.5cm} + Fazit: + \begin{itemize} + \item + \textbf{Adressen von Variablen\\ + sind systemabhängig} + \item + Bei Definition von Datenformaten\\ + Alignment beachten \textarrow\ effizienter + \end{itemize} + \end{minipage} + +\end{frame} + +\fi + +\end{document} diff --git a/common/io-ports-and-interrupts.eps b/common/io-ports-and-interrupts.eps new file mode 100644 index 0000000000000000000000000000000000000000..bf353a0fe55bc2185c28336bcbdb327d16903398 --- /dev/null +++ b/common/io-ports-and-interrupts.eps @@ -0,0 +1,3658 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Creator: dvips(k) 5.992 Copyright 2012 Radical Eye Software +%%Title: io-ports-and-interrupts.dvi +%%CreationDate: Sat Nov 19 19:25:00 2016 +%%BoundingBox: 145 496 435 642 +%%DocumentFonts: NimbusSanL-Regu +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -E io-ports-and-interrupts.dvi +%DVIPSParameters: dpi=1200 +%DVIPSSource: TeX output 2016.11.19:1924 +%%BeginProcSet: tex.pro 0 0 +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/CharBuilder{save 3 1 roll S A/base get 2 index get S +/BitMaps get S get/Cd X pop/ctr 0 N Cdx 0 Cx Cy Ch sub Cx Cw add Cy +setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx sub Cy .1 sub]{Ci}imagemask +restore}B/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/dir 0 def/dyy{/dir 0 def}B/dyt{/dir 1 def}B/dty{/dir 2 def}B/dtt{/dir 3 +def}B/p{dir 2 eq{-90 rotate show 90 rotate}{dir 3 eq{-90 rotate show 90 +rotate}{show}ifelse}ifelse}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 +N/Ry 0 N/V{}B/RV/v{/Ry X/Rx X V}B statusdict begin/product where{pop +false[(Display)(NeXT)(LaserWriter 16/600)]{A length product length le{A +length product exch 0 exch getinterval eq{pop true exit}if}{pop}ifelse} +forall}{false}ifelse end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{ +BDot}imagemask grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat +{BDot}imagemask grestore}}ifelse B/QV{gsave newpath transform round exch +round exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 +rlineto fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B +/M{S p delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M} +B/g{0 M}B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p +-3 w}B/n{p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{ +0 S rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: pstricks.pro 0 0 +% $Id: pstricks.pro 647 2012-02-12 15:03:40Z herbert $ +% +%% PostScript prologue for pstricks.tex. +%% Version 1.12, 2012/02/12 +%% +%% This program can be redistributed and/or modified under the terms +%% of the LaTeX Project Public License Distributed from CTAN archives +%% in directory macros/latex/base/lppl.txt. +% +% +% Define the follwing gs-functions if not known, eg when using distiller +% +systemdict /.setopacityalpha known not {/.setopacityalpha { pop } def } if +systemdict /.setblendmode known not {/.setblendmode { pop } def } if +systemdict /.setshapealpha known not {/.setshapealpha { pop } def } if +% +/tx@Dict 200 dict def % the main PSTricks dictionary +tx@Dict begin +/ADict 25 dict def % The arrow dictionaray +/CM { matrix currentmatrix } bind def +/SLW /setlinewidth load def +/CLW /currentlinewidth load def +/CP /currentpoint load def +/ED { exch def } bind def +/L /lineto load def +/T /translate load def +/TMatrix { } def +/RAngle { 0 } def +/Sqrt { dup 0 lt { pop 0 } { sqrt } ifelse } def % return 0 for negative arguments +/Atan { /atan load stopped { pop pop 0 } if } def % return 0 if atan not known +/ATAN1 {neg -1 atan 180 sub } def % atan(x) (only one parameter) +/Div { dup 0 eq { pop } { div } ifelse } def % control the division +/tan { dup cos abs 1.e-10 lt + { pop 1.e10 } % return 1.e10 as infinit + { dup sin exch cos div } ifelse % default sin/cos +} def +/Tan { dup sin exch cos Div } def % sin(x)/cos(x) x in degrees +/Acos {dup dup mul neg 1 add dup 0 lt { % arc cos, returns 0 when negative root + pop pop 0 }{ sqrt exch atan} ifelse } def +/NET { neg exch neg exch T } def % change coordinate system to the negative one +/Pyth { dup mul exch dup mul add sqrt } def % Pythagoras, expects 2 parameter +/Pyth2 { % Pythagoras, xA yA xB yB + 3 -1 roll % xA xB yB yA + sub % xA xB yB-yA + 3 1 roll % yB-yA xA xB + sub % yB-yA xA-xB + Pyth } def +/PtoC { 2 copy cos mul 3 1 roll sin mul } def % Polar to Cartesian +/Rand { rand 4294967295 div } def % a real random number +%----------------- hv added 20050516 --------------- +/PiDiv2 1.57079632680 def +/Pi 3.14159265359 def +/TwoPi 6.28318530718 def +/Euler 2.71828182846 def +%/e Euler bind def +% +/RadtoDeg { 180 mul Pi div } bind def % convert from radian to degrees +/DegtoRad { Pi mul 180 div } bind def % viceversa +%----------------- hv end--------------------------- +/PathLength@ { /z z y y1 sub x x1 sub Pyth add def /y1 y def /x1 x def } def +% +/PathLength { + flattenpath /z 0 def + { /y1 ED /x1 ED /y2 y1 def /x2 x1 def } + { /y ED /x ED PathLength@ } + {} + { /y y2 def /x x2 def PathLength@ } + /pathforall load stopped { pop pop pop pop } if + z +} def +% +/STP { .996264 dup scale } def % BP/PT scaling +/STV { SDict begin normalscale end STP } def % +% +/DashLine { + dup 0 gt + { /a .5 def PathLength exch div } + { pop /a 1 def PathLength } ifelse + /b ED % pattern should fit evenly in b + dup /X ED % pattern array + 0 get /y ED % length of first black segment + /z 0 X {add} forall def % length of the full pattern + %% Computation of the scaling factor as described by van Zandt: + b a .5 sub 2 mul y mul sub z Div round + z mul a .5 sub 2 mul y mul add b exch Div + %%%% scaling factor on stack. + /z ED %% now, z is the scaling factor + false % for the length test below + X { z mul } forall X astore %% modification TN 04-08-07 + %%% Checking whether at least one dash in X has positive length: + {0 gt or} forall + { X 1 a sub y mul } + { [ 1 0 ] 0 } + ifelse + setdash stroke +} def +% +/DotLine { + /b PathLength def + /a ED /z ED /y CLW def + /z y z add def + a 0 gt { + /b b a div def + }{ + a 0 eq { + /b b y sub def + }{ a -3 eq { + /b b y add def } if + } ifelse + } ifelse + [ 0 b b z Div round Div dup 0 le { pop 1 } if ] + a 0 gt { 0 }{ y 2 div a -2 gt { neg }if } ifelse + setdash 1 setlinecap stroke +} def +% +/SymbolLine { % on stack [ x y x y ... + counttomark % number of elements + 2 div cvi /n ED % n pairs + /YA ED /XA ED % the start point + n 1 sub { + /YB ED /XB ED + /XLength XB XA sub def + /YLength YB YA sub def + /PAngle YLength XLength Atan def + /XYLength XLength YLength Pyth def + + %% for negative SymStep we calculate the distance + SymStep 0 lt + { %XYLength SymStep div abs cvi + /nSym SymStep abs cvi def } + { /nSym XYLength SymStep div cvi def } + ifelse + 0.5 setflat + /Shift Symbol stringwidth pop 2 div def + /deltaX XLength nSym div def + /deltaY YLength nSym div def + curveticks + { XA YA moveto } + { XA Shift sub YA Shift sub moveto } + ifelse + nSym { + gsave + curveticks + { PAngle 180 sub CorrAngle sub tickAngle add /rotAngle ED + currentpoint translate rotAngle rotate + 0 SymbolWidth 2 div moveto 0 SymbolWidth 2 div neg lineto + SymbolLinewidth setlinewidth stroke + } + { + rotateSymbol { PAngle 180 sub CorrAngle sub rotate } if + Symbol show + } + ifelse + grestore + deltaX deltaY rmoveto + } repeat + /YA YB def /XA XB def + } repeat + curveticks + { XA YA moveto } + { XA Shift sub YA Shift sub moveto } + ifelse + gsave + curveticks + { PAngle 180 sub CorrAngle sub tickAngle add /rotAngle ED + XA YA translate rotAngle rotate + 0 SymbolWidth 2 div moveto 0 SymbolWidth 2 div neg lineto + SymbolLinewidth setlinewidth stroke + } + { + rotateSymbol { PAngle 180 sub CorrAngle sub rotate } if + Symbol show + } + ifelse + grestore + pop % delete the mark symbol +} def +% +/LineFill { % hv ------------ patch 7 ------------- + gsave + abs /hatchWidthInc ED + abs /hatchSepInc ED + abs CLW add /a ED + a 0 dtransform round exch round exch + 2 copy idtransform + exch Atan rotate + idtransform pop /a ED + .25 .25 itransform pathbbox + /y2 ED + a Div ceiling cvi /x2 ED /y1 ED + a Div cvi /x1 ED /y2 y2 y1 sub def + clip + newpath + 2 setlinecap + systemdict + /setstrokeadjust known { true setstrokeadjust } if + x2 x1 sub 1 add { + x1 a mul y1 moveto 0 y2 rlineto stroke + /x1 x1 1 add + hatchWidthInc 0 gt { CLW add } if + def + hatchSepInc 0 gt hatchWidthInc 0 gt or { + /a a hatchSepInc add def + CLW hatchWidthInc add SLW + } if + } repeat + grestore + pop pop } def +% +/DotFill {% on stack: dot radius + /dotRadius ED + abs CLW add /a ED + a 0 dtransform round exch round exch + 2 copy idtransform + exch Atan rotate + idtransform pop /a ED + .25 .25 itransform + pathbbox % llx lly urx ury of smallest bounding box + /y2 ED /x2 ED /y1 ED /x1 ED + y2 y1 sub a div 2 add cvi /Ny ED + x2 x1 sub a div 2 add cvi /Nx ED + clip + newpath + /yA y1 dotRadius add CLW add def + /xA0 x1 dotRadius add CLW add def + Ny { + /xA xA0 def + Nx { + newpath + xA yA dotRadius 0 360 arc + SolidDot { gsave fill grestore } if + stroke + xA a add /xA ED + } repeat + yA a add /yA ED + } repeat + grestore +} def +% +/PenroseFill {% on stack: scaling factor + dup dup scale + 1 exch div round /penroseFactor ED + a 0 dtransform round exch round exch + 2 copy idtransform + exch Atan rotate + idtransform pop /a ED + .25 .25 itransform pathbbox + /y2 ED + a Div ceiling cvi /x2 ED /y1 ED + a Div cvi /x1 ED /y2 y2 y1 sub def + clip + newpath + systemdict + /setstrokeadjust known { true setstrokeadjust } if + /I/S/L/W/G/+/Z/F/E/D[/def/exch/for{E D}/add{s E get mul} + { Z -36.2001 1 33 }{25 E S rlineto}{/q Z dup q G E q 1 + G}{Z 2 2}]{cvx def}forall + [0 72 1008 {dup sin E cos }F ]1 setlinejoin/s W{/a W{/b I 10{/i I 4{/m I moveto + i m +/j I 10{/l Z b m l + G a l G sub s m get div .2 + floor .3 + 25 + mul j l + S rmoveto}F i L j L stroke }F}F}F}F + grestore + pop pop +} def +% +/TruchetFill { % on stack: scaling factor + 10 dict begin + dup dup scale + 1 exch div round /penroseFactor ED + a 0 dtransform round exch round exch + 2 copy idtransform + exch Atan rotate + idtransform pop /a ED + .25 .25 itransform pathbbox + /y2 ED + a Div ceiling cvi /x2 ED /y1 ED + a Div cvi /x1 ED /y2 y2 y1 sub def + clip + newpath + systemdict + /setstrokeadjust known { true setstrokeadjust } if + /ma a neg def + /ha a 2 div def + /mha ha neg def + /tile { + rand dup 2 idiv 2 mul eq { 90 rotate } if + mha mha moveto ha mha lineto + ha ha lineto mha ha lineto +% closepath .1 setlinewidth stroke + contents + } def + /contents{ + 0 ha moveto ha 0 lineto + 0 mha moveto mha 0 lineto +% 1 setlinewidth stroke + } def + /dotiling { + f ma mul a f a mul { + /i exch def + f ma mul a f a mul { + /j exch def + gsave i j translate + tile stroke grestore + } for + } for + } def +% + /f 3 def + 5 srand dotiling + end % local user dict +} def +% +/BeginArrow { + ADict begin % hold it local, for end see EndArrow + /@mtrx CM def + gsave + 2 copy T + 2 index sub neg exch + 3 index sub exch Atan + rotate newpath +} def +% +/EndArrow { @mtrx setmatrix CP grestore end } def % end the ADict +% +/Arrow { + CLW mul add dup + 2 div /w ED + mul dup /h ED + mul /a ED + { 0 h T 1 -1 scale } if + w neg h moveto + 0 0 L w h L w neg a neg rlineto + gsave fill grestore +} def +% +/ArrowD { % the sides are drawn as curves (hv 20071211) + CLW mul add dup + 2 div /w ED + mul dup /h ED + mul /Inset ED + { 0 h T 1 -1 scale } if % changes the direction +% we use y=w/h^2 * x^2 as equation for the control points +% for the coordinates the arrow is seen from top to bottom +% the bottom (tip) is (0;0) + w neg h moveto % lower left of > + w 9 div 4 mul neg h 3 div 2 mul + w 9 div neg h 3 div + 0 0 curveto % tip of > + w 9 div h 3 div + w 9 div 4 mul h 3 div 2 mul + w h curveto % upper left of > + w neg Inset neg rlineto % move to x=0 and inset + gsave fill grestore +} def +% +/Tbar { + CLW mul add /z ED + z -2 div CLW 2 div moveto + z 0 rlineto stroke + 0 CLW moveto +} def +% +/Bracket { + CLW mul add dup CLW sub 2 div + /x ED mul CLW add /y ED /z CLW 2 div def + x neg y moveto + x neg CLW 2 div L x CLW 2 div L x y L stroke + 0 CLW moveto +} def +% +/RoundBracket { + CLW mul add dup 2 div + /x ED mul /y ED /mtrx CM def + 0 CLW 2 div T x y mul 0 ne { x y scale } if + 1 1 moveto + .85 .5 .35 0 0 0 curveto + -.35 0 -.85 .5 -1 1 curveto + mtrx setmatrix stroke 0 CLW moveto +} def +% +/SD { 0 360 arc fill } def +% +/EndDot { % DS is the dot size + { /z DS def } { /z 0 def } ifelse % outer or inner dimen + /b ED % the color definition + 0 z DS SD + b { 0 z DS CLW sub SD } if + 0 DS z add CLW 4 div sub + moveto +} def +% +/Shadow { [ { /moveto load } { /lineto load } { /curveto load } { + /closepath load } /pathforall load stopped { pop pop pop pop CP /moveto + load } if ] cvx newpath 3 1 roll T exec } def +% +/NArray { % holds the coordinates and on top of stack the showpoints boolean + /showpoints ED + counttomark 2 div dup cvi /n ED % n 2 div on stack + n eq not { exch pop } if % even numbers of points? delete one + ] aload /Points ED + showpoints not { Points aload pop } if +% { ] aload /Points ED } +% { n 2 mul 1 add -1 roll pop } ifelse % delete the mark symbol +} def +% +/Line { + NArray n 0 eq not + { n 1 eq { 0 0 /n 2 def } if ArrowA /n n 2 sub def + n { Lineto } repeat + CP 4 2 roll ArrowB L pop pop + } if +} def +% +/LineToYAxis { + /Ox ED % Save the x origin value + NArray % all x-y pairs on stack + n { 2 copy moveto % go to current point + Ox exch Lineto % line to y-axis + pop % delete old x-value + } repeat +} def +% +/LineToXAxis{ + /Oy ED % Save the y origin value + NArray % all x-y pairs on stack + n 0 eq not + { n 1 eq { 0 0 /n 2 def } if + ArrowA + /n n 2 sub def + CP 2 copy moveto pop Oy Lineto + n { 2 copy moveto pop Oy Lineto } repeat + CP + 4 2 roll + ArrowB + 2 copy moveto pop Oy + L + pop pop } if +} def +% +/Arcto { + /a [ 6 -2 roll ] cvx def + a r + /arcto load stopped { 5 } { 4 } ifelse { pop } repeat + a +} def +% +/CheckClosed { + dup n 2 mul 1 sub index eq 2 index n 2 mul 1 add index eq + and { pop pop /n n 1 sub def } if +} def +% +/Polygon { + NArray n 2 eq { 0 0 /n 3 def } if + n 3 lt + { n { pop pop } repeat } + { n 3 gt { CheckClosed } if + n 2 mul -2 roll + /y0 ED /x0 ED /y1 ED /x1 ED + x1 y1 + /x1 x0 x1 add 2 div def + /y1 y0 y1 add 2 div def + x1 y1 moveto + /n n 2 sub def + n { Lineto } repeat + x1 y1 x0 y0 6 4 roll Lineto + Lineto pop pop closepath } ifelse +} def +% +/SymbolPolygon { % on stack [ x y x y ... + counttomark % number of elements + 2 add /m ED + 2 copy m 2 roll % copy last two + m 2 div cvi /n ED % n pairs + /YA ED /XA ED % the start point + n 1 sub { + /YB ED /XB ED + /XLength XB XA sub def + /YLength YB YA sub def + /PAngle YLength XLength Atan def + /XYLength XLength YLength Pyth def + /nSym XYLength SymStep Div cvi def + /Shift Symbol stringwidth pop 2 Div def + /deltaX XLength nSym Div def + /deltaY YLength nSym Div def + XA Shift sub YA Shift sub moveto + nSym { + gsave rotateSymbol { PAngle 180 sub CorrAngle sub rotate } if + Symbol show + grestore + deltaX deltaY rmoveto + } repeat +% XB Shift sub YB Shift sub moveto Symbol show + /YA YB def /XA XB def + } repeat + pop % delete the mark symbol +} def +% +/Diamond { + /mtrx CM def + T rotate + /h ED + /w ED + dup 0 eq { pop } { CLW mul neg + /d ED + /a w h Atan def + /h d a sin Div h add def + /w d a cos Div w add def } ifelse + mark w 2 div h 2 div w 0 0 h neg w neg 0 0 h w 2 div h 2 div + /ArrowA { moveto } def + /ArrowB { } def + false Line + closepath mtrx setmatrix } def +% +/Triangle { + /mtrx CM def + translate + rotate /h ED 2 div /w ED + dup CLW mul /d ED + /h h d w h Atan sin Div sub def + /w w d h w Atan 2 div dup cos exch sin Div mul sub def + mark + 0 d w neg d 0 h w d 0 d + /ArrowA { moveto } def + /ArrowB { } def + false + Line + closepath + mtrx +% DG/SR modification begin - Jun. 1, 1998 - Patch 3 (from Michael Vulis) +% setmatrix } def + setmatrix pop +} def +% DG/SR modification end +% +/CCA { + /y ED /x ED + 2 copy y sub /dy1 ED + x sub /dx1 ED + /l1 dx1 dy1 Pyth def +} def +% +/CC { + /l0 l1 def + /x1 x dx sub def + /y1 y dy sub def + /dx0 dx1 def + /dy0 dy1 def + CCA + /dx dx0 l1 c exp mul dx1 l0 c exp mul add def + /dy dy0 l1 c exp mul dy1 l0 c exp mul add def + /m dx0 dy0 Atan dx1 dy1 Atan sub 2 div cos abs b exp a mul dx dy Pyth Div 2 div def + /x2 x l0 dx mul m mul sub def + /y2 y l0 dy mul m mul sub def + /dx l1 dx mul m mul neg def + /dy l1 dy mul m mul neg def +} def +% +/IC { + /c c 1 add def + c 0 lt { /c 0 def } { c 3 gt { /c 3 def } if } ifelse + /a a 2 mul 3 div 45 cos b exp div def + CCA + /dx 0 def + /dy 0 def +} def +% +/BOC { IC CC x2 y2 x1 y1 ArrowA CP 4 2 roll x y curveto } def +/NC { CC x1 y1 x2 y2 x y curveto } def +/EOC { x dx sub y dy sub 4 2 roll ArrowB 2 copy curveto } def +/BAC { IC CC x y moveto CC x1 y1 CP ArrowA } def +/NAC { x2 y2 x y curveto CC x1 y1 } def +/EAC { x2 y2 x y ArrowB curveto pop pop } def +% +/OpenCurve { + NArray n 3 lt + { n { pop pop } repeat } + { BOC /n n 3 sub def n { NC } repeat EOC } ifelse +} def +% +/CurvePath { + %% for negative SymStep we calculate the distance + SymStep 0 lt { gsave PathLength SymStep div abs /SymStep ED grestore } if + 0.5 setflat + flattenpath /z 0 def /z0 0 def + { /y1 ED /x1 ED /y2 y1 def /x2 x1 def + x1 Shift sub y1 Shift sub moveto + gsave + curveticks + { x1 y1 translate startAngle rotate + 0 SymbolWidth 2 div moveto 0 SymbolWidth 2 div neg lineto + SymbolLinewidth setlinewidth stroke + } + { startAngle rotate Symbol show } + ifelse + grestore /z0 z def } + { /y ED /x ED PathLength@ z z0 sub SymStep ge { + x Shift sub y Shift sub moveto + gsave + curveticks + { y yOld sub x xOld sub Atan 180 sub CorrAngle sub /rotAngle ED + x y translate rotAngle rotate + 0 SymbolWidth 2 div moveto 0 SymbolWidth 2 div neg lineto + SymbolLinewidth setlinewidth stroke + } + { + rotateSymbol { y yOld sub x xOld sub Atan 180 sub CorrAngle sub rotate } if + Symbol show + } + ifelse + grestore /z0 z def } if + /yOld y def /xOld x def } + {} %% the lineto part + { /y y2 def /x x2 def PathLength@ + x Shift sub y Shift sub moveto + gsave + curveticks + { y yOld sub x xOld sub Atan 180 sub /rotAngle ED + x y translate rotAngle rotate + 0 SymbolWidth 2 div moveto 0 SymbolWidth 2 div neg lineto + SymbolLinewidth setlinewidth stroke + } + { + x Shift sub y Shift sub moveto + rotateSymbol { y yOld sub x xOld sub Atan 180 sub CorrAngle sub rotate } if + Symbol show + } + ifelse + grestore + } + pathforall +% curveticks +% { gsave +% x y translate rotAngle rotate +% 0 SymbolWidth 2 div moveto 0 SymbolWidth 2 div neg lineto +% SymbolLinewidth setlinewidth stroke grestore +% } if + z +} def +% +/OpenSymbolCurve { + OpenCurve + 0.1 setflat + /Shift Symbol stringwidth pop 2 div def + CurvePath +} def +% +/AltCurve { + { false NArray n 2 mul 2 roll + [ n 2 mul 3 sub 1 roll ] aload + /Points ED + n 2 mul -2 roll } + { false NArray } ifelse + n 4 lt { n { pop pop } repeat } { BAC /n n 4 sub def n { NAC } repeat EAC } ifelse +} def +% +/AltOpenSymbolCurve { + AltCurve + 0.1 setflat + /Shift Symbol stringwidth pop 2 div def + CurvePath +} def +% +/ClosedCurve { + NArray n 3 lt + { n { pop pop } repeat } + { n 3 gt { CheckClosed } if + 6 copy n 2 mul 6 add 6 roll + IC CC x y moveto n { NC } repeat + closepath pop pop + } ifelse +} def +% +/ClosedSymbolCurve { + ClosedCurve + 0.1 setflat + /Shift Symbol stringwidth pop 2 div def + CurvePath +} def +% +/SQ { /r ED r r moveto r r neg L r neg r neg L r neg r L fill } def +/ST { /y ED /x ED x y moveto x neg y L 0 x L fill } def +/SP { /r ED gsave 0 r moveto 4 { 72 rotate 0 r L } repeat fill grestore } def +% +/FontDot { + DS 2 mul dup + matrix scale matrix concatmatrix exch matrix + rotate matrix concatmatrix exch + findfont exch makefont setfont +} def +% +/Rect { + x1 y1 y2 add 2 div moveto + x1 y2 lineto + x2 y2 lineto + x2 y1 lineto + x1 y1 lineto + closepath +} def +% +/OvalFrame { + x1 x2 eq y1 y2 eq or + { pop pop x1 y1 moveto x2 y2 L } + { y1 y2 sub abs x1 x2 sub abs 2 copy gt + { exch pop } { pop } ifelse + 2 div exch { dup 3 1 roll mul exch } if + 2 copy lt { pop } { exch pop } ifelse + /b ED + x1 y1 y2 add 2 div moveto + x1 y2 x2 y2 b arcto + x2 y2 x2 y1 b arcto + x2 y1 x1 y1 b arcto + x1 y1 x1 y2 b arcto + 16 { pop } repeat + closepath + } ifelse +} def +% +/Frame { + CLW mul /a ED + 3 -1 roll + 2 copy gt { exch } if + a sub /y2 ED + a add /y1 ED + 2 copy gt { exch } if + a sub /x2 ED + a add /x1 ED + 1 index 0 eq { pop pop Rect } { OvalFrame } ifelse +} def +% +/BezierNArray { + /f ED + counttomark 2 div dup cvi /n ED + n eq not { exch pop } if + n 1 sub neg 3 mod 3 add 3 mod { 0 0 /n n 1 add def } repeat + f { ] aload /Points ED } { n 2 mul 1 add -1 roll pop } ifelse +} def +% +/OpenBezier { + BezierNArray + n 1 eq + { pop pop } + { ArrowA n 4 sub 3 idiv + { 6 2 roll 4 2 roll curveto } repeat + 6 2 roll 4 2 roll ArrowB curveto } ifelse +} def +% +/OpenSymbolBezier { + OpenBezier + 0.1 setflat + /Shift Symbol stringwidth pop 2 div def + CurvePath +} def +% +/ClosedBezier { + BezierNArray + n 1 eq + { pop pop } + { moveto n 1 sub 3 idiv + { 6 2 roll 4 2 roll curveto } repeat + closepath } ifelse +} def +% +/ClosedSymbolBezier { + /f ED % save showpoints value + 2 copy /yEnd ED /xEnd ED + counttomark -2 roll 2 copy /yStart ED /xStart ED + counttomark 2 roll + f + ClosedBezier + 0.1 setflat + /Shift Symbol stringwidth pop 2 div def + CurvePath + [ xEnd yEnd xStart yStart SymbolLine +} def +% +/BezierShowPoints { + gsave + Points aload length 2 div cvi /n ED + moveto + n 1 sub { lineto } repeat + CLW 2 div SLW [ 4 4 ] 0 setdash stroke + grestore +} def +% +/Parab { + /y0 ED /x0 ED /y1 ED /x1 ED + /dx x0 x1 sub 3 div def + /dy y0 y1 sub 3 div def + x0 dx sub y0 dy add x1 y1 ArrowA + x0 dx add y0 dy add x0 2 mul x1 sub y1 ArrowB + curveto + /Points [ x1 y1 x0 y0 x0 2 mul x1 sub y1 ] def +} def +% +/Parab1 { % 1 end | 0 SP + /ySP ED /xSP ED /y1 ED /x1 ED + /dx xSP x1 sub 3 div def + /dy ySP y1 sub 3 div def + newpath x1 y1 moveto xSP y1 lineto xSP ySP lineto + x1 ySP lineto closepath clip + currentpoint + newpath moveto + xSP dx sub ySP dy add x1 y1 ArrowA + xSP dx add ySP dy add xSP 2 mul x1 sub y1 ArrowB + curveto + /Points [ x1 y1 xSP ySP xSP 2 mul x1 sub y1 ] def +} def +% +/Grid { + newpath + /a 4 string def + /b ED % psk@gridlabels in pt + /c ED % { \pst@usecolor\psgridlabelcolor } + /n ED % psk@griddots + cvi dup 1 lt { pop 1 } if + /s ED % \psk@subgriddiv + s div dup 0 eq { pop 1 } if + /dy ED s div dup 0 eq { pop 1 } if % \pst@number\psyunit abs + /dx ED dy div round dy mul % \pst@number\psxunit abs + /y0 ED dx div round dx mul + /x0 ED dy div round cvi + /y2 ED dx div round cvi + /x2 ED dy div round cvi + /y1 ED dx div round cvi + /x1 ED + /h y2 y1 sub 0 gt { 1 } { -1 } ifelse def + /w x2 x1 sub 0 gt { 1 } { -1 } ifelse def + b 0 gt { + /z1 b 4 div CLW 2 div add def +% /Helvetica findfont b scalefont setfont + /b b .95 mul CLW 2 div add def } if + systemdict /setstrokeadjust known + { true setstrokeadjust /t { } def } + { /t { transform 0.25 sub round 0.25 add exch 0.25 sub round 0.25 add + exch itransform } bind def } ifelse + gsave n 0 gt { 1 setlinecap [ 0 dy n div ] dy n div 2 div setdash } { 2 setlinecap } ifelse + /i x1 def + /f y1 dy mul n 0 gt { dy n div 2 div h mul sub } if def + /g y2 dy mul n 0 gt { dy n div 2 div h mul add } if def + x2 x1 sub w mul 1 add dup 1000 gt { pop 1000 } if + { i dx mul dup y0 moveto + b 0 gt + { gsave c i a cvs dup stringwidth pop + /z2 ED w 0 gt {z1} {z1 z2 add neg} ifelse + h 0 gt {b neg}{z1} ifelse + rmoveto show grestore } if + dup t f moveto + g t L stroke + /i i w add def + } repeat + grestore + gsave + n 0 gt + % DG/SR modification begin - Nov. 7, 1997 - Patch 1 + %{ 1 setlinecap [ 0 dx n div ] dy n div 2 div setdash } + { 1 setlinecap [ 0 dx n div ] dx n div 2 div setdash } + % DG/SR modification end + { 2 setlinecap } ifelse + /i y1 def + /f x1 dx mul n 0 gt { dx n div 2 div w mul sub } if def + /g x2 dx mul n 0 gt { dx n div 2 div w mul add } if def + y2 y1 sub h mul 1 add dup 1000 gt { pop 1000 } if + { newpath i dy mul dup x0 exch moveto + b 0 gt { gsave c i a cvs dup stringwidth pop + /z2 ED + w 0 gt {z1 z2 add neg} {z1} ifelse + h 0 gt {z1} {b neg} ifelse + rmoveto show grestore } if + dup f exch t moveto + g exch t L stroke + /i i h add def + } repeat + grestore +} def +% +/ArcArrow { + /d ED /b ED /a ED + gsave + newpath 0 -1000 moveto clip + newpath + 0 1 0 0 b + grestore + c mul + /e ED + pop pop pop r a e d PtoC y add exch x add + exch r a PtoC y add exch x add exch b pop pop pop pop a e d CLW 8 div c + mul neg d +} def +% +/Ellipse { + /rotAngle ED + /mtrx CM def + T + rotAngle rotate + scale 0 0 1 5 3 roll arc + mtrx setmatrix +} def +% +/ArcAdjust { %%%% Vincent Guirardel +% given a target length (targetLength) and an initial angle (angle0) [in the stack], +% let M(angle0)=(rx*cos(angle0),ry*sin(angle0))=(x0,y0). +% This computes an angle t such that (x0,y0) is at distance +% targetLength from the point M(t)=(rx*cos(t),ry*sin(t)). +% NOTE: this an absolute angle, it does not have to be added or substracted to angle0 +% contrary to TvZ's code. +% To achieve, this, one iterates the following process: start with some angle t, +% compute the point M' at distance targetLength of (x0,y0) on the semi-line [(x0,y0) M(t)]. +% Now take t' (= new angle) so that (0,0) M(t') and M' are aligned. +% +% Another difference with TvZ's code is that we need d (=add/sub) to be defined. +% the value of d = add/sub is used to know on which side we have to move. +% It is only used in the initialisation of the angle before the iteration. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Input stack: 1: target length 2: initial angle +% variables used : rx, ry, d (=add/sub) +% + /targetLength ED /angle0 ED + /x0 rx angle0 cos mul def + /y0 ry angle0 sin mul def +% we are looking for an angle t such that (x0,y0) is at distance targetLength +% from the point M(t)=(rx*cos(t),ry*sin(t))) +%initialisation of angle (using 1st order approx = TvZ's code) + targetLength 57.2958 mul + angle0 sin rx mul dup mul + angle0 cos ry mul dup mul + add sqrt div +% if initialisation angle is two large (more than 90 degrees) set it to 90 degrees +% (if the ellipse is very curved at the point where we draw the arrow, % +% the value can be much more than 360 degrees !) +% this should avoid going on the wrong side (more than 180 degrees) or go near +% a bad attractive point (at 180 degrees) + dup 90 ge { pop 90 } if + angle0 exch d % add or sub +% maximum number of times to iterate the iterative procedure: +% iterative procedure: takes an angle t on top of stack, computes a +% better angle (and put it on top of stack) + 30 { dup +% compute distance D between (x0,y0) and M(t) + dup cos rx mul x0 sub dup mul exch sin ry mul y0 sub dup mul add sqrt +% if D almost equals targetLength, we stop + dup targetLength sub abs 1e-5 le { pop exit } if +% stack now contains D t +% compute the point M(t') at distance targetLength of (x0,y0) on the semi-line [(x0,y0) M(t)]: +% M(t')= ( (x(t)-x0)*targetLength/d+x0 , (y(t)-y0)*targetLength/d+y0 ) + exch dup cos rx mul x0 sub exch sin ry mul y0 sub +% stack contains: y(t)-y0, x(t)-x0, d + 2 index Div targetLength mul y0 add ry Div exch + 2 index Div targetLength mul x0 add rx Div +% stack contains x(t')/rx , y(t')/ry , d +% now compute t', and remove D from stack + atan exch pop + } repeat +% we don't look at what happened... in particular, if targetLength is greater +% than the diameter of the ellipse... +% the final angle will be around /angle0 + 180. maybe we should treat this pathological case... +% after iteration, stack contains an angle t such that M(t) is the tail of the arrow +% to give back the result as a an angle relative to angle0 we could add the following line: +% angle0 sub 0 exch d +% +% begin bug fix 2006-01-11 +% we want to adjust the new angle t' by a multiple of 360 so that | t'-angle0 | <= 180 +%(we don't want to make the ellipse turn more or less than it should)... +dup angle0 sub dup abs 180 gt { 180 add 360 div floor 360 mul sub } { pop } ifelse +% end bug fix +} def +% +/EllipticArcArrow { + /d ED % is add or sub + /b ED % arrow procedure + /a1 ED % angle + gsave + newpath + 0 -1000 moveto + clip % Set clippath far from arrow. + newpath + 0 1 0 0 b % Draw arrow to determine length. + grestore +% Length of arrow is on top of stack. Next 3 numbers are junk. +% + a1 exch ArcAdjust % Angular position of base of arrow. + /a2 ED + pop pop pop + a2 cos rx mul xOrig add % hv 2007-08-29 x->xOrig + a2 sin ry mul yOrig add % hv 2007-08-29 y->yOrig + a1 cos rx mul xOrig add % + a1 sin ry mul yOrig add % +% Now arrow tip coor and base coor are on stack. + b pop pop pop pop % Draw arrow, and discard coordinates. + a2 CLW 8 div +% change value of d (test it by looking if `` 1 1 d '' gives 2 or not ) + 1 1 d 2 eq { /d { sub } def } { /d { add } def } ifelse + ArcAdjust +% resets original value of d + 1 1 d 2 eq { /d { sub } def } { /d { add } def } ifelse % Adjust angle to give overlap. +} def +%%------------------ tvz/DG/hv (2004-05-10) end -------------------%% +% +/Rot { CP CP translate 3 -1 roll neg rotate NET } def +% +/RotBegin { + tx@Dict /TMatrix known not { /TMatrix { } def /RAngle { 0 } def } if + /TMatrix [ TMatrix CM ] cvx def + /a ED + a Rot /RAngle [ RAngle dup a add ] cvx def +} def +% +/RotEnd { + /TMatrix [ TMatrix setmatrix ] cvx def + /RAngle [ RAngle pop ] cvx def +} def +% +/PutCoor { gsave CP T CM STV exch exec moveto setmatrix CP grestore } def +/PutBegin { /TMatrix [ TMatrix CM ] cvx def CP 4 2 roll T moveto } def +/PutEnd { CP /TMatrix [ TMatrix setmatrix ] cvx def moveto } def +% +/Uput { + /a ED + add 2 div /h ED 2 + div /w ED + /s a sin def + /c a cos def + /b s abs c abs 2 copy gt dup + /q ED + { pop } { exch pop } ifelse def + /w1 c b div w mul def + /h1 s b div h mul def + q { w1 abs w sub dup c mul abs }{ h1 abs h sub dup s mul abs } ifelse +} def +% +/UUput { + /z ED + abs /y ED + /x ED + q { x s div c mul abs y gt }{ x c div s mul abs y gt } ifelse + { x x mul y y mul sub z z mul add sqrt z add } + { q { x s div } { x c div } ifelse abs + } ifelse + a PtoC + h1 add exch + w1 add exch +} def +% +/BeginOL { + dup (all) eq exch TheOL eq or + { IfVisible not { Visible /IfVisible true def } if } + { IfVisible { Invisible /IfVisible false def } if } ifelse +} def +% +/InitOL { + /OLUnit [ 3000 3000 matrix defaultmatrix dtransform ] cvx def + /Visible { CP OLUnit idtransform T moveto } def + /Invisible { CP OLUnit neg exch neg exch idtransform T moveto } def + /BOL { BeginOL } def + /IfVisible true def +} def +% +%%%%%%%%%%%%%%%%% tools %%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% ### bubblesort ### +%% syntax : array bubblesort --> array2 trie par ordre croissant +%% code de Bill Casselman +%% http://www.math.ubc.ca/people/faculty/cass/graphics/text/www/ +/bubblesort { +4 dict begin + /a exch def + /n a length 1 sub def + n 0 gt { + % at this point only the n+1 items in the bottom of a remain to + % the sorted largest item in that blocks is to be moved up into + % position n + n { + 0 1 n 1 sub { + /i exch def + a i get a i 1 add get gt { + % if a[i] > a[i+1] swap a[i] and a[i+1] + a i 1 add + a i get + a i a i 1 add get + % set new a[i] = old a[i+1] + put + % set new a[i+1] = old a[i] + put + } if + } for + /n n 1 sub def + } repeat + } if + a +end +} def +% +% +/concatstringarray{ % [(a) (b) ... (z)] --> (ab...z) 20100422 + 0 1 index { length add } forall + string + 0 3 2 roll + { 3 copy putinterval length add }forall + pop +} bind def +% +/dot2comma {% on stack a string (...) + 2 dict begin + /Output exch def + 0 1 Output length 1 sub { + /Index exch def + Output Index get 46 eq { Output Index 44 put } if + } for + Output + end +} def +% +end +%-----------------------------------------------------------------------------% +% +% END pstricks.pro + +%%EndProcSet +%%BeginProcSet: pst-algparser.pro 0 0 +% $Id: pst-algparser.pro 594 2011-10-31 18:13:18Z herbert $ +%% +%% PostScript prologue for PSTricks algorithm parser +%% Version 0.04, 2011/10/21 +%% +%% This program can be redistributed and/or modified under the terms +%% of the LaTeX Project Public License Distributed from CTAN archives +%% in directory macros/latex/base/lppl.txt. +%% +%%-----------------------------------------------------------------------------% +% +/AlgParser { tx@AlgToPs begin AlgToPs end } def % Dominique Rodriguez +% +/tx@CoreAnalyzerDict 100 dict def tx@CoreAnalyzerDict begin +% +% PS ANALYZER FOR ALGEBRAIC EXPRESSION V1.13 +% +% 09/2011 DR factorial with ! added +% +% E->T|E+T +% T->FS|T*FS +% FS -> F | +FS | -FS +% F->P|F^SF|P! +% P->(E)|literal +% literal->number|var|var[E]|func(params) +% params->E|E,param +% number->TOBEFINISHED +% +%% E expression, T term, SF signed factor, F factor, P power +% +%% parser +% +%% str +% +%% C->E<condition_operators>E +%% STR index -> STR index+lenExpr +/AnalyzeCond { AnalyzeExpr ReadCondOp AnalyzeExpr EvalCondOp } def +% +%% analyze Expression List (separator , or | ) +%% STR index -> STR index+lenExpr +%% /AnalyzeListOfE { +%% { NextNonBlankChar pop AnalyzeExpr%%dup Strlen eq { exit } if NextNonBlankChar +%% NextNonBlankChar dup 0 eq { pop exit } if +%% dup 44 ne 1 index 124 ne and { dup 41 ne { PROBLEMCONTACTBILLOU } { pop exit } ifelse } if +%% pop NextNonBlankChar dup 0 eq { exit } if 124 ne { PROBLEMCONTACTBILLOU } if 1 add NextNonBlankChar 0 eq {toto} if } loop +%% AnalyzeListOfEPostHook +%% } def +/AnalyzeListOfE { + /NotFirst false def + { NextNonBlankChar pop AnalyzeExpr + NotFirst { EvalListOfExpr } { /NotFirst true def } ifelse + dup Strlen eq { exit } if NextNonBlankChar + dup 44 ne 1 index 124 ne and + { dup 41 ne { PROBLEMCONTACTBILLOU } { pop exit } ifelse } + if pop 1 add } loop + AnalyzeListOfEPostHook +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% E->T|E+T +%% STR index -> STR index+lenExpr +/AnalyzeExpr { + AnalyzePreHook AnalyzeTerm IsEndingExpr + { dup 0 ne { 32 eq { NextNonBlankChar } if } { pop } ifelse } + { { RollOp 1 add NextNonBlankChar pop AnalyzeTerm PreEvalHook EvalAddSub IsEndingExpr { pop exit } if } loop } + ifelse + AnalyzePostHook +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% T->FS|T*FS +%% STR index +/AnalyzeTerm { + AnalyzePreHook AnalyzeSignedFactor IsEndingTerm + { dup 0 ne { 32 eq { NextNonBlankChar } if } { pop } ifelse } + { { RollOp 1 add NextNonBlankChar pop AnalyzeSignedFactor PreEvalHook EvalMulDiv IsEndingTerm { pop exit } if} loop } + ifelse + AnalyzePostHook +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% FS -> F | +FS | -FS +%% STR index +/AnalyzeSignedFactor { + AnalyzePreHook 2 copy get dup IsUnaryOp + { RollOp 1 add NextNonBlankChar pop AnalyzeSignedFactor EvalUnaryOp } + { pop AnalyzeFactor } + ifelse AnalyzePostHook +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% F->P|F^P|P! +%% STR index +/AnalyzeFactor { + AnalyzePreHook AnalyzePower IsEndingFactor + { dup 0 ne { 32 eq { NextNonBlankChar } if } { pop } ifelse } + { { dup 33 eq%% is there a ! DR 09/2011 + { pop 1 add NextNonBlankChar pop EvalFactorial } + { RollOp 1 add NextNonBlankChar pop AnalyzePower PreEvalHook EvalPower } + ifelse + IsEndingFactor { pop exit } if } loop } + ifelse AnalyzePostHook +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% P->(E)|literal +%% STR index +/AnalyzePower { + %% depending of first char either a number, or a literal + 2 copy get dup 40 eq%%an open par + { pop 1 add NextNonBlankChar pop AnalyzeExpr 1 add NextNonBlankChar pop } + { AnalyzeLiteral } + ifelse +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% STR index STR[index] -> STR index +%/AnalyzeLiteral { IsNumber { EvalNumber } { EvalLiteral } ifelse } def +/AnalyzeLiteral { dup IsUnaryOp exch IsNumber or { EvalNumber } { EvalLiteral } ifelse } def%%dr 09102006 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% recognize + or - +%% chr -> T/F +/IsUnaryOp { dup 43 eq exch 45 eq or } bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% a number can contain only : 0123456789. +%% chr -> T/F +/IsNumber { dup 48 ge exch dup 57 le 3 -1 roll and exch 46 eq or } bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% STR index -> STR index number +%% a number can be of the form [0-9]*.[0-9]*\([eE][+-]?[0-9]+\)? +%% STR index -> STR index' number +/ReadNumber { + exch dup 3 -1 roll dup 3 1 roll + %%read mantissa + { 1 add 2 copy dup Strlen eq { pop pop 0 exit } if get dup IsNumber not { exit } if pop } loop + dup 101 eq exch 69 eq or + %%% there is a "e" or "E" -> read exponant + { 1 add 2 copy get dup IsUnaryOp + { pop 1 add 2 copy get } if + { IsNumber not { exit } if 1 add 2 copy get } loop } + if + dup 4 1 roll + 3 -1 roll exch 1 index sub getinterval +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% a number can contain only : 0123456789. +%% chr -> T/F +/IsCondOp { dup 30 eq exch dup 60 ge exch 62 le and or } bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% STR index -> STR index number +%% a number can be of the form [0-9]*.[0-9]*\([eE][+-]?[0-9]+\)? +%% STR index -> STR index' number +/ReadCondOp { + NextNonBlankChar 1 index 4 1 roll + { IsCondOp not { exit } if 1 add 2 copy get } loop + 2 copy 5 -1 roll + exch 1 index sub getinterval 3 1 roll +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% a literal can contain only : 0123456789. +%% chr -> T/F +/IsLiteral {% + dup 48 ge exch dup 57 le 3 -1 roll and exch + dup 65 ge exch dup 90 le 3 -1 roll and 3 -1 roll or exch + dup 97 ge exch 122 le and or } bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% a literal can be of the form [a-zA-Z][a-zA-Z0-9]*\(\((Expression)\)|\(\[Expression\]\)\)? +%% STR index -> literal STR index' nextchr +/ReadLiteral { + exch dup 3 -1 roll dup 3 1 roll + %%read literal core + { 2 copy dup Strlen eq { pop pop 0 exit } if get dup IsLiteral not { exit } if pop 1 add } loop + 4 1 roll dup 5 1 roll 3 -1 roll exch 1 index sub getinterval 4 1 roll +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% expr is ended by end of str or a clpar +%% STR index -> STR index STR[index] T/F +/IsEndingExpr {% + 2 copy dup Strlen eq + %% if end of str is reached -> end ! + { pop pop 0 true } + %% ending chr -> clpar, comma, |, <, >, =, !, + {get dup dup 41 eq + exch dup 124 eq + exch dup 93 eq + exch dup 44 eq + exch dup 30 eq + exch dup 60 ge exch 62 le and or or or or or} + ifelse } def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% expr is ended by end of str or a +- +%% STR index -> STR index STR[index] T/F +/IsEndingTerm { IsEndingExpr { true } { dup dup 43 eq exch 45 eq or } ifelse } def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% expr is ended by end of str or */ +%% STR index -> STR index STR[index] T/F +/IsEndingFactor { IsEndingTerm { true } { dup dup 42 eq exch 47 eq or } ifelse } def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% expr is ended by end of str or ^ +%% STR index -> STR index STR[index] T/F +/IsEndingPower { IsEndingFactor { true } { dup 94 eq } ifelse } def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% STR index -> STR index STR[index] +/NextNonBlankChar { { dup Strlen eq { 0 exit } if 2 copy get dup neBlkChar { exit } if pop 1 add } loop } bind def +/neBlkChar { dup 32 ne exch dup 10 ne exch 9 ne and and } bind def +%%%%%%%%%%%%%%%%%%%%%%%% +%% DEBUG +/BRK {false} def +/BRKtrue {/BRK true def} def +/BRKStop {BRK {BRKtoto} if } def +/BRKEvalStop {BRK exch if } def +/BRKBRK2true {BRK {BRK2true} if } def +/BRK2 {false} def +/BRK2true {/BRK2 true def} def +/BRK2Stop {BRK2 {BRK2toto} if } def/BRK {false} def +end +% +%-------------------------------------------------------------------------------% +% +/tx@AlgToPs 12 dict def tx@AlgToPs begin +% +%% algExpr -> PSVector +/AlgToPs { tx@CoreAnalyzerDict begin InitParser AnalyzeListOfE pop pop EndingSequence end } def +/EndingSequence { ExpressionVector aload length /end cvx exch 1 add array astore } def +/InitParser { /ExpressionVector [ /tx@AddMathFunc cvx /begin cvx ] def dup length /Strlen exch def 0 } def +/Strlen 0 def +/EvalListOfExpr {} def% +/EvalNumber {% + ReadNumber cvr /ExpressionVector ExpressionVector aload length dup 3 add -1 roll cvx + exch 1 add array astore def NextNonBlankChar pop } def +/EvalAddSub {% + /ExpressionVector ExpressionVector aload length dup 5 add -1 roll + 43 eq { /add } { /sub } ifelse cvx exch 1 add array astore def +} def +/EvalMulDiv {% + /ExpressionVector ExpressionVector aload length dup 5 add -1 roll + 42 eq { /mul } { /div } ifelse cvx exch 1 add array astore def +} def +/EvalPower {% + /ExpressionVector ExpressionVector aload length dup 5 add -1 roll + pop /exp cvx exch 1 add array astore def +} def +/EvalFactorial {% DR 09/2011 + /ExpressionVector ExpressionVector aload length + /fact cvx exch 1 add array astore def +} def +/EvalLiteral {% + ReadLiteral + dup 40 eq%%% there is an open par -> function call + { pop 2 index + dup (Sum) eq { EvalSum } + { dup (IfTE) eq { EvalCond } + { dup (Derive) eq { pop EvalDerive } + { pop 1 add NextNonBlankChar pop AnalyzeListOfE 2 index TrigoFunc + /ExpressionVector ExpressionVector aload length dup 5 add -1 roll cvn cvx + exch 1 add array astore def 1 add NextNonBlankChar pop } ifelse } ifelse} ifelse } + { /ExpressionVector ExpressionVector aload length dup 6 add -1 roll cvn cvx exch 1 add array astore def + dup 91 eq%%% there is an open bracket -> vector element + { pop 1 add NextNonBlankChar pop AnalyzeExpr + /ExpressionVector ExpressionVector aload length /cvi cvx exch /get cvx exch 2 add array astore def 1 add } + { pop NextNonBlankChar pop } + ifelse} + ifelse +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% the derive function : Derive(n,f(x)) +%% firstparindex lastparindex -> +/EvalDerive { + %% manage the function descripiton + 1 add ReadNumber 3 1 roll NextNonBlankChar + 44 ne { ANALYZER_ERROR_missing_second_comma_in_Sum } if + 1 add NextNonBlankChar pop + 3 -1 roll cvi + dup 0 eq + { pop AnalyzeExpr 3 -1 roll pop 1 add } + { 1 sub 3 1 roll (x) exch tx@Derive begin DeriveIndexed end 4 -1 roll + { (x) tx@Derive begin Derive end } repeat + ExpressionVector exch /ExpressionVector [] def + AlgToPs aload length + /ExpressionVector 1 index 3 add -1 roll aload length dup 3 add -1 roll /l2 exch def /l1 exch def + l1 l2 add 1 add l2 neg roll l1 l2 add array astore def 3 -1 roll pop 1 add + 1 index length /Strlen exch def } ifelse +} def +/EvalSum {% + pop 1 add NextNonBlankChar pop + %% read the variable name + ReadLiteral pop NextNonBlankChar + 44 ne { ANALYZER_ERROR_missing_first_comma_in_Sum } if + %% read the initial value + 1 add NextNonBlankChar pop ReadNumber cvi 3 1 roll + 2 copy get 44 ne { ANALYZER_ERROR_missing_second_comma_in_Sum } if + %% read the increment value + 1 add NextNonBlankChar pop ReadNumber cvi 3 1 roll + 2 copy get 44 ne { ANALYZER_ERROR_missing_second_comma_in_Sum } if + %% read the limit value + 1 add NextNonBlankChar pop ReadNumber cvi 3 1 roll + 2 copy get 44 ne { ANALYZER_ERROR_missing_second_comma_in_Sum } if + /ExpressionVector ExpressionVector aload length dup 7 add -3 roll 0 4 1 roll + 5 -1 roll 4 add array astore def + %% keep ExpressionVector for later and create a new one for internal Sum computation + ExpressionVector 3 1 roll /ExpressionVector [ 6 -1 roll cvn /exch cvx /def cvx ] def + 1 add NextNonBlankChar pop AnalyzeExpr + %% add each term + /ExpressionVector ExpressionVector aload length 1 add /add cvx exch array astore def + /ExpressionVector 4 -1 roll aload length ExpressionVector cvx /for cvx 3 -1 roll 2 add + array astore def 3 -1 roll pop 1 add +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Convert to radians if trigo function call +%% (name) -> +/TrigoFunc { + dup (cos) eq 1 index (sin) eq or exch (tan) eq or + { /ExpressionVector ExpressionVector aload length Pi /div cvx 180 /mul cvx 5 -1 roll 4 add + array astore def + } if +} def +/EvalCond {% + pop 1 add AnalyzeCond NextNonBlankChar + 44 ne { ANALYZER_ERROR_missing_first_comma_in_IfTE } if + ExpressionVector 3 1 roll /ExpressionVector [] def + 1 add AnalyzeExpr ExpressionVector 3 1 roll /ExpressionVector [] def + NextNonBlankChar 44 ne { ANALYZER_ERROR_missing_second_comma_in_IfTE } if + 1 add AnalyzeExpr + NextNonBlankChar 41 ne { ANALYZER_ERROR_missing_ending parenthesis_in_IfTE } if + ExpressionVector + /ExpressionVector 6 -1 roll aload length dup + 6 add -1 roll cvx exch dup 4 add -1 roll cvx /ifelse cvx 3 -1 roll 3 add array astore def + 1 add 3 -1 roll pop +} def +%% CondOp STR index +/EvalCondOp {% + 3 -1 roll + dup (=) eq { /eq } {% + dup (<) eq { /lt } {% + dup (>) eq { /gt } {% + dup (>=) eq { /ge } {% + dup (<=) eq { /ge } {% + dup (!=) eq { /ne } { ERROR_non_valid_conditional_operator } + ifelse } ifelse } ifelse } ifelse } ifelse } ifelse + cvx exch pop + /ExpressionVector ExpressionVector aload length dup 3 add -1 roll exch 1 add array astore def } def +/EvalUnaryOp { + 3 -1 roll 45 eq { /ExpressionVector ExpressionVector aload length /neg cvx exch 1 add array astore def } if +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% H O O K S +/AnalyzePreHook {} bind def +/PreEvalHook {} bind def +/AnalyzeListOfEPostHook {} bind def +/AnalyzePostHook {} def +/RollOp { 3 1 roll } bind def +end %tx@CoreAnalyzerDict +% +%--------------------------------------------------------------------% +% +/tx@Derive 41 dict def tx@Derive begin +%%increase ^^ for each function added +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% algExpr variable -> PSVector +/Derive {% + 10240 string 3 1 roll 0 3 1 roll + /Variable exch def + tx@CoreAnalyzerDict begin InitParser AnalyzeListOfE end +} def +/Strlen 0 def +/InitParser { dup length /Strlen exch def 0 } def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% algExpr variable index -> PSVector +/DeriveIndexed {% + 3 1 roll 10240 string 3 1 roll 0 3 1 roll + /Variable exch def + tx@CoreAnalyzerDict begin InitParser pop 4 -1 roll AnalyzeExpr 4 -2 roll pop pop 4 -2 roll exch pop end +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% (u,v)'=-(u',v') +/EvalListOfExpr {% + 4 2 roll 2 copy 9 -1 roll dup length 4 1 roll putinterval add AddPipe + 2 copy 7 -1 roll dup length 4 1 roll putinterval add + 6 -2 roll pop pop + 2 copy pop 0 6 2 roll GetIntervalNewStr 5 1 roll 2 copy 0 exch getinterval 6 1 roll } def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% (-u)'=-(u') +/EvalUnaryOp { + 4 -2 roll 4 index (0) eq + { (0) StrConcat 7 -1 roll pop } + { 7 -1 roll 45 eq + { AddSub AddOpPar true } { false } ifelse + 3 1 roll 5 index StrConcat 3 -1 roll { AddClPar } if } ifelse + 2 copy pop 0 6 2 roll GetIntervalNewStr + 7 -2 roll pop pop 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% (number)'=0 +/EvalNumber { ReadNumber (0) 6 2 roll } def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% (u+v)'=u'+v' +/EvalAddSub {% + 7 index dup (0) eq + { pop true }%% du=0 nothing added + { dup length exch 5 index 5 index 3 -1 roll putinterval 4 -1 roll add 3 1 roll false } + ifelse + 5 index dup (0) eq + { pop { (0) } { 4 -2 roll 2 copy pop 0 6 2 roll GetIntervalNewStr } ifelse }%%dv=0 + { exch + { 5 -2 roll 7 index 45 eq { AddSub } if false } %%nothing yet added + { 5 -2 roll 7 index 43 eq%%something yet added + { AddAdd false } { AddSub AddOpPar true } ifelse } + ifelse 11 1 roll + 3 -1 roll StrConcat 10 -1 roll { AddClPar } if + 2 copy pop 0 6 2 roll GetIntervalNewStr } + ifelse + mark 11 -5 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% (u*v)' or (u/v)' +/EvalMulDiv { 6 index 42 eq {EvalMul} {EvalDiv} ifelse } def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% (u*v)'=u'*v+u*v' +/EvalMul {% + 4 -2 roll 7 index dup (0) eq + { pop false }%%du=0 + { (1) eq%%du=1 + { false } + { AddOpPar 7 index StrConcat AddClPar AddMul AddOpPar true } ifelse + 3 1 roll 6 index StrConcat 3 -1 roll { AddClPar } if + true }%%du!=0 + ifelse + 5 1 roll 5 index (0) eq + { 5 -1 roll not { (0) StrConcat } if }%%dv=0 + { 5 -1 roll { AddAdd } if + 4 index (1) eq + { 8 index StrConcat } + { AddOpPar 8 index StrConcat AddClPar AddMul AddOpPar 4 index StrConcat AddClPar } + ifelse + }%%dv!=0 + ifelse + 2 copy pop 0 6 2 roll GetIntervalNewStr + mark 11 -5 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% (u/v)'=(u'*v-u*v')/v^2 +/EvalDiv {% + 4 -2 roll + 4 index (0) eq%%dv=0 -> u'/v + { 7 index (0) eq { (0) StrConcat } { AddOpPar 7 index StrConcat AddClPar AddDiv 5 index StrConcat } ifelse } + { 7 index dup (0) eq + { pop }%%du=0 + { (1) eq%%du=1 + { false } + { AddOpPar 7 index StrConcat AddClPar AddMul AddOpPar true } ifelse + 3 1 roll 6 index StrConcat 3 -1 roll { AddClPar } if}%%du!=0 + ifelse + AddSub + 4 index (1) eq + { 8 index StrConcat } + { AddOpPar 8 index StrConcat AddClPar AddMul AddOpPar 4 index StrConcat AddClPar } + ifelse + %}%%dv!=0 + 2 copy GetIntervalNewStr 3 1 roll pop 0 AddOpPar 3 -1 roll StrConcat AddClPar + AddDiv AddOpPar 5 index StrConcat AddClPar 2 copy (^2) putinterval 2 add } + ifelse + 2 copy pop 0 6 2 roll GetIntervalNewStr + mark 11 -5 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% str1 index str2 -> str1 index +/StrConcat { dup length 4 2 roll 2 copy 6 -1 roll putinterval 3 -1 roll add } bind def +/GetIntervalNewStr { 0 exch getinterval dup length string copy } bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% (u^v)'=(u^v)'=u'vu^(v-1)+v'u^(v)ln(u) +/EvalPower {% + 4 -2 roll 7 index (0) eq + {%%if du=0 then (u^v)'=v'ln(u)u^v + 4 index (0) eq + { (0) StrConcat }%%if dv=0 then (u^v)'=0 + { 4 index (1) ne { AddOpPar 4 index StrConcat (\)*) StrConcat } if + 8 index (e) ne { (ln\() StrConcat 8 index StrConcat (\)*) StrConcat } if + AddOpPar 8 index StrConcat (\)^\() StrConcat 5 index StrConcat AddClPar } ifelse + } + {%%du!=0 + 4 index (0) eq + {%%if dv=0 then (u^v)'=vu'u^(v-1) + 5 index dup IsStrNumber + { dup (0) eq + { StrConcat } + { dup dup (1) eq exch (1.0) eq or + { StrConcat } + { StrConcat + 7 index dup (1) ne exch (1.0) ne and%%%dr 09102006 insert du if <> 1 + { (*\() StrConcat 7 index StrConcat (\)) StrConcat } if%%%dr 09102006 + (*\() StrConcat 8 index StrConcat (\)) StrConcat + 5 index dup dup (2) eq exch (2.0) eq or + { pop } { cvr 1 sub 20 string cvs 3 1 roll (^) StrConcat 3 -1 roll StrConcat } ifelse } ifelse } ifelse } + { pop AddOpPar 5 index StrConcat (\)*\() StrConcat 8 index StrConcat (\)^\() StrConcat + 5 index StrConcat (-1\)) StrConcat } ifelse + } + {%%if dv!=0 and du!=0 then (u^v)'=u'vu^(v-1)+v'u^(v)ln(u) + 7 index (1) ne { AddOpPar 7 index StrConcat (\)*) StrConcat } if + AddOpPar 5 index StrConcat (\)*\() StrConcat + 8 index StrConcat (\)^\() StrConcat + 5 index StrConcat (-1\)+\() StrConcat + 4 index (1) ne { 4 index StrConcat (\)*\() StrConcat } if + 8 index StrConcat (\)^\() StrConcat + 5 index StrConcat (\)*ln\() StrConcat + 8 index StrConcat AddClPar + } ifelse + } ifelse + 2 copy pop 0 6 2 roll GetIntervalNewStr + mark 11 -5 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% No derivative for factorial ! only cst => null derivative +/EvalFactorial {% DR 09/2011 + 4 index (0) eq + { (0) mark 8 -2 roll cleartomark 2 index 7 index dup 4 index exch sub getinterval exch 6 2 roll } + { DERIVATIVE_ENGINE_ERROR_no_variable_in_factorial } ifelse +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% str -> true/false +/IsStrNumber {% + true exch + { dup 48 lt exch dup 57 gt 3 -1 roll or + exch dup 46 ne%%. + exch dup 43 ne%%+ + exch 45 ne%%- + and and and { pop false } if } forall +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% literal switch -> func call, vector, variables +/EvalLiteral {% + ReadLiteral dup 40 eq%%% there is an open par -> function call + { pop (EvalFunc_ ) 9 4 index StrConcat 0 exch getinterval cvn cvx exec } + { dup 91 eq%%% there is an open bracket -> vector element + { DERIVATIVE_ENGINE_ERROR_vector_not_yet_implemented } + { pop EvalVariable } + ifelse } + ifelse +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% first last parpos Expr[first:parpos-1] -> +/EvalVariable { 2 index Variable eq { (1) } { (0) } ifelse 4 -1 roll exch 6 2 roll } def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% (f(u))'=u'f'(u) +/EvalFunc { + 4 2 roll 4 index (1) ne + { AddOpPar 4 index StrConcat (\)*) StrConcat } if + (Eval ) 4 8 index StrConcat 0 exch getinterval cvn cvx exec + 2 copy pop 0 6 2 roll GetIntervalNewStr + mark 9 -3 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Func derivative -> Eval<func> +/EvalFunc_sin {% + PreCommonFunc + { (cos\() StrConcat 5 index StrConcat AddClPar } if + PostCommonFunc } def +/EvalFunc_cos {% + PreCommonFunc + { (\(-sin\() StrConcat 5 index StrConcat (\)\)) StrConcat } if + PostCommonFunc } def +/EvalFunc_tan {% + PreCommonFunc + { dup 0 eq { (1) StrConcat } { 1 sub } ifelse (/cos\() StrConcat 5 index StrConcat (\)^2) StrConcat } if + PostCommonFunc } def +/EvalFunc_asin {% + PreCommonFunc + { (1/sqrt\(1-\() StrConcat 5 index StrConcat (\)^2\)\)) StrConcat } if + PostCommonFunc } def +/EvalFunc_acos {% + PreCommonFunc + { (-1/sqrt\(1-\() StrConcat 5 index StrConcat (\)^2\)\)) StrConcat } if + PostCommonFunc } def +/EvalFunc_atg {% + PreCommonFunc + { (1/\(1+\() StrConcat 5 index StrConcat (\)^2\)\)) StrConcat } if + PostCommonFunc } def +/EvalFunc_ln {% + PreCommonFunc + { dup 0 eq { (1) StrConcat } { 1 sub } ifelse (/\() StrConcat 5 index StrConcat AddClPar } if + PostCommonFunc } def +/EvalFunc_exp {% + PreCommonFunc + { (exp\() StrConcat 5 index StrConcat AddClPar } if + PostCommonFunc } def +/EvalFunc_EXP {% + PreCommonFunc + { (EXP\() StrConcat 5 index StrConcat AddClPar } if + PostCommonFunc } def +/EvalFunc_sqrt {% + PreCommonFunc + { dup 0 eq { (1) StrConcat } { 1 sub } ifelse (/\(2*sqrt\() StrConcat 5 index StrConcat (\)\)) StrConcat } if + PostCommonFunc } def +/EvalFunc_Fact {% + PreCommonFunc { DERIVATIVE_ENGINE_ERROR_no_variable_expression_in_Fact } if + PostCommonFunc } def +/EvalFunc_sh {% + PreCommonFunc + { (ch\() StrConcat 5 index StrConcat AddClPar } if + PostCommonFunc } def +/EvalFunc_ch {% + PreCommonFunc + { (sh\() StrConcat 5 index StrConcat AddClPar } if + PostCommonFunc } def +/EvalFunc_th {% + PreCommonFunc + { dup 0 eq { (1) StrConcat } { 1 sub } ifelse (/ch\() StrConcat 5 index StrConcat (\)^2) StrConcat } if + PostCommonFunc } def +/EvalFunc_Argsh {% + PreCommonFunc + { (1/sqrt\(1+\() StrConcat 5 index StrConcat (\)^2\)\)) StrConcat } if + PostCommonFunc } def +/EvalFunc_Argch {% + PreCommonFunc + { (1/sqrt\(\() StrConcat 5 index StrConcat (\)^2-1\)\)) StrConcat } if + PostCommonFunc } def +/EvalFunc_Argth {% + PreCommonFunc + { (1/\(1-\() StrConcat 5 index StrConcat (\)^2\)\)) StrConcat } if + PostCommonFunc } def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/PreCommonFunc { + 1 add NextNonBlankChar pop 3 -1 roll 5 1 roll AnalyzeExpr 1 add NextNonBlankChar pop + 4 2 roll 4 index (0) eq + { (0) StrConcat false } + { 4 index (1) ne { AddOpPar 4 index StrConcat (\)*) StrConcat } if true } ifelse +} def +/PostCommonFunc { + 2 copy pop 0 6 2 roll GetIntervalNewStr + mark 9 -3 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll +} def +/EvalFunc_Derive {% + 1 add ReadNumber cvi 1 add dup cvr log 1 add cvi string cvs + 4 -1 roll pop 5 1 roll 1 add NextNonBlankChar pop AnalyzeExpr 1 add + 4 -2 roll (Derive\() StrConcat 7 -1 roll StrConcat (,) StrConcat 6 -1 roll StrConcat AddClPar + 2 copy pop 0 6 2 roll GetIntervalNewStr 6 -1 roll pop 2 index 6 index dup 4 index exch sub getinterval + exch 6 2 roll } def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% literal switch -> func call, vector, variables +/EvalFunc_Sum {% + 1 add NextNonBlankChar pop + %% read the variable name + ReadLiteral pop 3 -1 roll pop NextNonBlankChar + 44 ne { ANALYZER_ERROR_missing_first_comma_in_Sum } if + %% read the initial value + 1 add NextNonBlankChar pop ReadNumber pop + 2 copy get 44 ne { ANALYZER_ERROR_missing_second_comma_in_Sum } if + %% read the increment value + 1 add NextNonBlankChar pop ReadNumber pop + 2 copy get 44 ne { ANALYZER_ERROR_missing_third_comma_in_Sum } if + %% read the limit value + 1 add NextNonBlankChar pop ReadNumber pop + 2 copy get 44 ne { ANALYZER_ERROR_missing_fourth_comma_in_Sum } if + 1 add NextNonBlankChar pop dup 6 1 roll 3 -1 roll pop AnalyzeExpr 1 add NextNonBlankChar pop + 4 -2 roll 3 index 8 index dup 9 index exch sub getinterval StrConcat + 4 index StrConcat AddClPar + 2 copy pop 0 6 2 roll GetIntervalNewStr + mark 9 -3 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% literal switch -> func call, vector, variables +/EvalFunc_IfTE {% + 3 -1 roll pop 1 add NextNonBlankChar pop SkipCond + NextNonBlankChar + 44 ne { ANALYZER_ERROR_missing_first_comma_in_IfTE } if + 1 add NextNonBlankChar pop dup 5 1 roll + AnalyzeExpr NextNonBlankChar + 44 ne { ANALYZER_ERROR_missing_second_comma_in_IfTE } if + 1 add NextNonBlankChar pop + AnalyzeExpr 1 add NextNonBlankChar pop + 4 -2 roll 3 index 10 index dup 11 index exch sub getinterval StrConcat + 6 index StrConcat (,) StrConcat 4 index StrConcat AddClPar + 2 copy pop 0 6 2 roll GetIntervalNewStr + mark 11 -5 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% advance in str until a comma is found (no error detection!) +%% str index -> str index' +/SkipCond { { 1 add 2 copy get 44 eq {exit } if } loop } bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Convert to radians if trigo function call +%% (name) -> +/TrigoFunc { + dup (cos) eq 1 index (sin) eq or exch (tan) eq or + { /ExpressionVector ExpressionVector aload length Pi /div cvx 180 /mul cvx 5 -1 roll 4 add + array astore def + } if +} def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% No derivative for condition.... +/EvalCondOp { 3 -1 roll pop } bind def +/PutIntervalOneAdd {putinterval 1 add} bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Add open parenthesis in string at the given index +%% str index -> str index+1 +/AddOpPar {2 copy (\() PutIntervalOneAdd} bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Add close parenthesis in string at the given index +%% str index -> str index+1 +/AddClPar {2 copy (\)) PutIntervalOneAdd} bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Add 0 in string at the given index +%% str index -> str index+1 +/AddZero {2 copy (0) PutIntervalOneAdd} bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Add open parenthesis in string at the given index +%% str index -> str index+1 +/AddMul {2 copy (*) PutIntervalOneAdd} bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Add open parenthesis in string at the given index +%% str index -> str index+1 +/AddDiv {2 copy (/) PutIntervalOneAdd} bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Add a plus sign in string at the given index +%% str index -> str index+1 +/AddAdd {2 copy (+) PutIntervalOneAdd} bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Add a minus sign in string at the given index +%% str index -> str index+1 +/AddSub {2 copy (-) PutIntervalOneAdd} bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Add a pipe sign in string at the given index +%% str index -> str index+1 +/AddPipe {2 copy (|) PutIntervalOneAdd} bind def +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% H O O K S +/AnalyzePreHook { dup 5 1 roll } bind def +/PreEvalHook {} def +/AnalyzePostHook { 7 -1 roll pop } bind def +/AnalyzeListOfEPostHook { 6 -1 roll mark 6 1 roll cleartomark } bind def +/RollOp { 5 1 roll } bind def +end%%%tx@CoreAnalyzerDict +/tx@AddMathFunc 12 dict def tx@AddMathFunc begin +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% NEW FUNC +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% function arcsine in radians asin(x)=atan(x/sqrt(1-x^2)) +%% x -> theta +/asin {% + dup abs 1 gt { EQDFasinrangeerror } if + dup dup dup mul 1 exch sub sqrt atan exch 0 lt { 360 sub } if DegtoRad +} def +%% function arccosine in radians acos(x)=atan(sqrt(1-x^2)/x) +%% x -> theta +/acos {% + dup abs 1 gt { EQDFacosrangeerror } if + dup dup mul 1 exch sub sqrt exch atan DegtoRad +} def +%% function arctangent in radians +%% x -> theta +/atg { 1 atan dup 90 gt { 360 sub } if DegtoRad } bind def +%% HYPERBOLIC FUNCTIONS +/sh { dup Ex exch neg Ex sub 2 div } def +/ch { dup Ex exch neg Ex add 2 div } def +/th { dup sh exch ch div } def +/Argsh { dup dup mul 1 add sqrt add ln } def +/Argch { dup dup mul 1 sub sqrt add ln } def +/Argth { dup 1 add exch 1 exch sub div ln 2 div } def +%% modified exponential funtion for 0 +%% x n -> x^n +/Exp { dup 0 eq { pop pop 1 } { exp } ifelse } bind def +%% modified exponential funtion for 0 +%% x -> e^x +/Ex { Euler exch exp } bind def +%% +%% factorial function +%% n -> n! +/Fact { 1 exch 2 exch 1 exch { mul } for } bind def +/fact { Fact } bind def +/! { Fact } bind def +end +% +% END pst-algparser.pro + +%%EndProcSet +%%BeginProcSet: pst-tools.pro 0 0 +% $Id: pst-tools.pro 622 2012-01-01 15:36:14Z herbert $ +% +%% PostScript tools prologue for pstricks.tex. +%% Version 0.02, 2012/01/01 +%% +%% This program can be redistributed and/or modified under the terms +%% of the LaTeX Project Public License Distributed from CTAN archives +%% in directory macros/latex/base/lppl.txt. +% +% +/Pi2 1.57079632679489661925640 def +/factorial { % n on stack, returns n! + dup 0 eq { 1 }{ + dup 1 gt { dup 1 sub factorial mul } if } + ifelse } def +% +/MoverN { % m n on stack, returns the binomial coefficient m over n + 2 dict begin + /n exch def /m exch def + n 0 eq { 1 }{ + m n eq { 1 }{ + m factorial n factorial m n sub factorial mul div } ifelse } ifelse + end +} def +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% subroutines for complex numbers, given as an array [a b] +% which is a+bi = Real+i Imag +% +/cxadd { % [a1 b1] [a2 b2] = [a1+a2 b1+b2] + dup 0 get % [a1 b1] [a2 b2] a2 + 3 -1 roll % [a2 b2] a2 [a1 b1] + dup 0 get % [a2 b2] a2 [a1 b1] a1 + 3 -1 roll % [a2 b2] [a1 b1] a1 a2 + add % [a2 b2] [a1 b1] a1+a2 + 3 1 roll % a1+a2 [a2 b2] [a1 b1] + 1 get % a1+a2 [a2 b2] b1 + exch 1 get % a1+a2 b1 b2 + add 2 array astore +} def +% +/cxneg { % [a b] + dup 1 get % [a b] b + exch 0 get % b a + neg exch neg % -a -b + 2 array astore +} def +% +/cxsub { cxneg cxadd } def % same as negative addition +% +% [a1 b1][a2 b2] = [a1a2-b1b2 a1b2+b1a2] = [a3 b3] +/cxmul { % [a1 b1] [a2 b2] + dup 0 get % [a1 b1] [a2 b2] a2 + exch 1 get % [a1 b1] a2 b2 + 3 -1 roll % a2 b2 [a1 b1] + dup 0 get % a2 b2 [a1 b1] a1 + exch 1 get % a2 b2 a1 b1 + dup % a2 b2 a1 b1 b1 + 5 -1 roll dup % b2 a1 b1 b1 a2 a2 + 3 1 roll mul % b2 a1 b1 a2 b1a2 + 5 -2 roll dup % b1 a2 b1a2 b2 a1 a1 + 3 -1 roll dup % b1 a2 b1a2 a1 a1 b2 b2 + 3 1 roll mul % b1 a2 b1a2 a1 b2 a1b2 + 4 -1 roll add % b1 a2 a1 b2 b3 + 4 2 roll mul % b1 b2 b3 a1a2 + 4 2 roll mul sub % b3 a3 + exch 2 array astore +} def +% +% [a b]^2 = [a^2-b^2 2ab] = [a2 b2] +/cxsqr { % [a b] square root + dup 0 get exch 1 get % a b + dup dup mul % a b b^2 + 3 -1 roll % b b^2 a + dup dup mul % b b^2 a a^2 + 3 -1 roll sub % b a a2 + 3 1 roll mul 2 mul % a2 b2 + 2 array astore +} def +% +/cxsqrt { % [a b] +% dup cxnorm sqrt /r exch def +% cxarg 2 div RadtoDeg dup cos r mul exch sin r mul cxmake2 + cxlog % log[a b] + 2 cxrdiv % log[a b]/2 + aload pop exch % b a + 2.781 exch exp % b exp(a) + exch cxconv exch % [Re +iIm] exp(a) + cxrmul % +} def +% +/cxarg { % [a b] + aload pop % a b + exch atan % arctan b/a + DegtoRad % arg(z)=atan(b/a) +} def +% +% log[a b] = [a^2-b^2 2ab] = [a2 b2] +/cxlog { % [a b] + dup % [a b][a b] + cxnorm % [a b] |z| + log % [a b] log|z| + exch % log|z|[a b] + cxarg % log|z| Theta + cxmake2 % [log|z| Theta] +} def +% +% square of magnitude of complex number +/cxnorm2 { % [a b] + dup 0 get exch 1 get % a b + dup mul % a b^2 + exch dup mul add % a^2+b^2 +} def +% +/cxnorm { % [a b] + cxnorm2 sqrt +} def +% +/cxconj { % conjugent complex + dup 0 get exch 1 get % a b + neg 2 array astore % [a -b] +} def +% +/cxre { 0 get } def % real value +/cxim { 1 get } def % imag value +% +% 1/[a b] = ([a -b]/(a^2+b^2) +/cxrecip { % [a b] + dup cxnorm2 exch % n2 [a b] + dup 0 get exch 1 get % n2 a b + 3 -1 roll % a b n2 + dup % a b n2 n2 + 4 -1 roll exch div % b n2 a/n2 + 3 1 roll div % a/n2 b/n2 + neg 2 array astore +} def +% +/cxmake1 { 0 2 array astore } def % make a complex number, real given +/cxmake2 { 2 array astore } def % dito, both given +% +/cxdiv { cxrecip cxmul } def +% +% multiplikation by a real number +/cxrmul { % [a b] r + exch aload pop % r a b + 3 -1 roll dup % a b r r + 3 1 roll mul % a r b*r + 3 1 roll mul % b*r a*r + exch 2 array astore % [a*r b*r] +} def +% +% division by a real number +/cxrdiv { % [a b] r + 1 exch div % [a b] 1/r + cxrmul +} def +% +% exp(i theta) = cos(theta)+i sin(theta) polar<->cartesian +/cxconv { % theta + RadtoDeg dup sin exch cos cxmake2 +} def + +%%%%% ### bubblesort ### +%% syntax : array bubblesort --> array2 trie par ordre croissant +%% code de Bill Casselman +%% http://www.math.ubc.ca/people/faculty/cass/graphics/text/www/ +/bubblesort { % on stack must be an array [ ... ] +4 dict begin + /a exch def + /n a length 1 sub def + n 0 gt { + % at this point only the n+1 items in the bottom of a remain to + % the sorted largest item in that blocks is to be moved up into + % position n + n { + 0 1 n 1 sub { + /i exch def + a i get a i 1 add get gt { + % if a[i] > a[i+1] swap a[i] and a[i+1] + a i 1 add + a i get + a i a i 1 add get + % set new a[i] = old a[i+1] + put + % set new a[i+1] = old a[i] + put + } if + } for + /n n 1 sub def + } repeat + } if + a % return the sorted array +end +} def +% +/concatstringarray{ % [(a) (b) ... (z)] --> (ab...z) 20100422 + 0 1 index { length add } forall + string + 0 3 2 roll + { 3 copy putinterval length add }forall + pop +} bind def +% +/dot2comma {% on stack a string (...) + 2 dict begin + /Output exch def + 0 1 Output length 1 sub { + /Index exch def + Output Index get 46 eq { Output Index 44 put } if + } for + Output + end +} def +% +%-----------------------------------------------------------------------------% +% END pst-tools.pro + +%%EndProcSet +%%BeginProcSet: pst-dots.pro 0 0 +% $Id: pst-dots.pro 130 2009-08-27 08:55:03Z herbert $ +% +%% PostScript prologue for pstricks.tex. +%% Version 2.02, 2009/06/16 +%% +%% For distribution, see pstricks.tex. +%% +%% Timothy Van Zandt <tvz@Princeton.EDU> +%% +%% This program can be redistributed and/or modified under the terms +%% of the LaTeX Project Public License Distributed from CTAN archives +%% in directory macros/latex/base/lppl.txt. +%% +%% Modified by Etienne Riga - Dec. 16, 1999 +%% Modified by Etienne Riga - 2005/01/01 (er) +%% to add /Diamond, /SolidDiamond and /BoldDiamond +%% Modified by Herbert Voss (hv) - 2008/04/17 +% +10 dict dup begin % hold local + /FontType 3 def + /FontMatrix [.001 0 0 .001 0 0] def +% /FontBBox [-571.5 -742.5 571.5 742.5] def % changed to next line 20060616 hv + /FontBBox [-1000 -1000 1000 1000] def % See end of file in /BuildGlyph + /Encoding 256 array def + 0 1 255 {Encoding exch /.notdef put} for % fill the array with /.notdef + Encoding % replace with given dot names + dup (b) 0 get /Bullet put % get the numerical position of b in ASCII +% % and save /Bullet at this place in Encoding + dup (c) 0 get /Circle put + dup (C) 0 get /BoldCircle put % 67 + dup (u) 0 get /SolidTriangle put + dup (t) 0 get /Triangle put + dup (T) 0 get /BoldTriangle put + dup (r) 0 get /SolidSquare put + dup (s) 0 get /Square put + dup (S) 0 get /BoldSquare put + dup (q) 0 get /SolidPentagon put + dup (p) 0 get /Pentagon put + dup (P) 0 get /BoldPentagon put +%%% + dup (k) 0 get /Asterisk put + dup (K) 0 get /BoldAsterisk put + dup (J) 0 get /SolidAsterisk put + dup (h) 0 get /Hexagon put + dup (H) 0 get /BoldHexagon put + dup (G) 0 get /SolidHexagon put + dup (f) 0 get /Octogon put % 2008-04-18 hv + dup (F) 0 get /BoldOctogon put % 2008-04-18 hv + dup (g) 0 get /SolidOctogon put % 2008-04-18 hv + dup (a) 0 get /Add put + dup (A) 0 get /BoldAdd put % 65 + dup (x) 0 get /Mul put + dup (X) 0 get /BoldMul put + dup (m) 0 get /Oplus put + dup (M) 0 get /BOplus put + dup (e) 0 get /SolidOplus put + dup (n) 0 get /Otimes put + dup (N) 0 get /BOtimes put + dup (E) 0 get /SolidOtimes put + dup (i) 0 get /Bar put + dup (I) 0 get /BoldBar put + dup (l) 0 get /SolidDiamond put + dup (d) 0 get /Diamond put + (D) 0 get /BoldDiamond put +%%% +/CharProcs 47 dict def +CharProcs begin + /CirclePath {0 0 500 0 360 arc closepath} def + /Bullet {CirclePath fill} def + /Circle {CirclePath .9 .9 scale CirclePath eofill} def + /BoldCircle {CirclePath .8 .8 scale CirclePath eofill} def + /TrianglePath {0 660 moveto -571.5 -330 lineto 571.5 -330 lineto closepath} def + /SolidTriangle {TrianglePath fill} def + /Triangle {TrianglePath .85 .85 scale TrianglePath eofill} def + /BoldTriangle {TrianglePath .7 .7 scale TrianglePath eofill} def + /SquarePath {-450 450 moveto 450 450 lineto 450 -450 lineto -450 -450 lineto closepath} def + /SolidSquare {SquarePath fill} def + /Square {SquarePath .89 .89 scale SquarePath eofill} def + /BoldSquare {SquarePath .78 .78 scale SquarePath eofill} def + /PentagonPath { + -337.8 -465 moveto 337.8 -465 lineto 546.6 177.6 lineto + 0 574.7 lineto -546.6 177.6 lineto closepath + } def + /SolidPentagon {PentagonPath fill} def + /Pentagon {PentagonPath .89 .89 scale PentagonPath eofill} def + /BoldPentagon {PentagonPath .78 .78 scale PentagonPath eofill} def +%-------------- hv begin 2004/07/25 from: er 2003/03/24 + /HexagonPath { + 0 550 moveto -476 275 lineto -476 -275 lineto + 0 -550 lineto 476 -275 lineto 476 275 lineto closepath + } def + /SolidHexagon {HexagonPath fill} def + /Hexagon {HexagonPath .89 .89 scale HexagonPath eofill} def + /BoldHexagon {HexagonPath .79 .79 scale HexagonPath eofill} def +% 2008-04-18 hv + /OctogonPath { + 550 dup 22.5 tan mul dup neg dup add /xMove exch def + exch moveto 7 { xMove 0 rlineto 45 rotate } repeat closepath } def + /SolidOctogon { OctogonPath fill } def + /Octogon { OctogonPath .89 .89 scale OctogonPath eofill } def + /BoldOctogon { OctogonPath .79 .79 scale OctogonPath eofill } def +% + /AsteriskPath { + 20 0 moveto 10 250 180 500 0 500 curveto + -180 500 -10 250 -20 0 curveto closepath + } def + /Asterisk { + AsteriskPath 60 rotate AsteriskPath 60 rotate AsteriskPath + 60 rotate AsteriskPath 60 rotate AsteriskPath 60 rotate AsteriskPath fill + } def +% + /Basterp {50 250 220 500 0 500 curveto -220 500 -50 250 -50 30 cos 100 mul curveto} def + /BoldAsteriskPath { + 50 30 cos 100 mul moveto Basterp + 60 rotate Basterp 60 rotate Basterp + 60 rotate Basterp 60 rotate Basterp + 60 rotate Basterp closepath + } def + /BoldAsterisk {BoldAsteriskPath fill} def + /SolidAsterisk {CirclePath .9 .9 scale BoldAsteriskPath eofill} def + /CrossPath { + 40 550 moveto -40 550 lineto -40 40 lineto -550 40 lineto + -550 -40 lineto -40 -40 lineto -40 -550 lineto 40 -550 lineto + 40 -40 lineto 550 -40 lineto 550 40 lineto 40 40 lineto closepath + } def + /BoldCrossPath {80 550 moveto -80 550 lineto -80 80 lineto -550 80 lineto + -550 -80 lineto -80 -80 lineto -80 -550 lineto 80 -550 lineto + 80 -80 lineto 550 -80 lineto 550 80 lineto 80 80 lineto closepath + } def + /Add {CrossPath fill} def + /Mul {45 rotate CrossPath fill} def + /BoldAdd {BoldCrossPath fill} def + /BoldMul {45 rotate BoldCrossPath fill} def + /Oplus {CirclePath .9 .9 scale CirclePath eofill .775 .775 scale CrossPath fill } def + /SolidOplus {CirclePath .775 .775 scale BoldCrossPath eofill} def + /BOplus {CirclePath .8 .8 scale CirclePath eofill .775 .775 scale BoldCrossPath fill} def + /Otimes {CirclePath .9 .9 scale CirclePath eofill 45 rotate .775 .775 scale CrossPath fill} def + /BOtimes {CirclePath .8 .8 scale CirclePath eofill 45 rotate .775 .775 scale BoldCrossPath fill } def + /SolidOtimes {CirclePath 45 rotate .775 .775 scale BoldCrossPath eofill} def + /BarPath {40 660 moveto -40 660 lineto -40 -660 lineto 40 -660 lineto closepath} def + /Bar {BarPath fill} def + /BoldBarPath {80 660 moveto -80 660 lineto -80 -660 lineto 80 -660 lineto closepath} def + /BoldBar {BoldBarPath fill} def + /DiamondPath {0 742.5 moveto -428.5 0 lineto 0 -742.5 lineto 428.5 0 lineto closepath} def + /SolidDiamond {DiamondPath fill} def + /Diamond {DiamondPath .865 .865 scale DiamondPath eofill} def + /BoldDiamond {DiamondPath .73 .73 scale DiamondPath eofill} def +%%% + /.notdef { } def +end +% +/BuildGlyph { + exch + begin +% Metrics 1 index get exec 0 + 0 0 +% BBoxes 3 index get exec + -1000 -1000 1000 1000 +% -571.5 -742.5 571.5 742.5 + setcachedevice + CharProcs begin load exec end + end +} def +% +/BuildChar { + 1 index /Encoding get exch get + 1 index /BuildGlyph get exec +} bind def +% +end +/PSTricksDotFont exch definefont pop +% +%% end + +%%EndProcSet +%%BeginProcSet: pst-node.pro 0 0 +% $Id: pst-node.pro 645 2012-02-12 09:09:51Z herbert $ +%% +%% PostScript prologue for pst-node.tex. +%% Version 1.13, 2011/11/21. +%% +%% This program can be redistributed and/or modified under the terms +%% of the LaTeX Project Public License Distributed from CTAN archives +%% in directory macros/latex/base/lppl.txt. +% +/tx@NodeDict 400 dict def tx@NodeDict begin +tx@Dict begin % from main pstricks dict + /T /translate load def + /CP /currentpoint load def +end +/NewNode { % on stack: { x y } boolean N@name type InitXnode + gsave + NodeScale % a bugfix for xelatex, it's empty for dvips + /next exch def % { x y } boolean N@name type + dict dup % { x y } boolean N@name dict dict + 3 1 roll def % { x y } boolean dict N@name dict def + exch { dup 3 1 roll def } if % { x y } dict boolean + begin % { x y } dict begin + tx@Dict begin + STV CP T exec % set scaling + end + /NodeMtrx CM def % save CM + next % InitXNode + end + grestore +} def +% +/InitPnode { + /Y ED /X ED + /NodePos { NodeSep Cos mul NodeSep Sin mul } def +} def +% +/InitCnode { + /r ED /Y ED /X ED + /NodePos { NodeSep r add dup Cos mul exch Sin mul } def +} def +% +/GetRnodePos { + Cos 0 gt { /dx r NodeSep add def } { /dx l NodeSep sub def } ifelse + Sin 0 gt { /dy u NodeSep add def } { /dy d NodeSep sub def } ifelse + dx Sin mul abs dy + Cos mul abs gt { dy Cos mul Sin div dy } { dx dup Sin mul Cos Div } ifelse +} def +% +/InitRnode { + /Y ED /X ED X sub /r ED /l X neg def Y add neg /d ED Y sub /u ED + /NodePos { GetRnodePos } def +} def +% +/DiaNodePos { + w h mul w Sin mul abs h Cos mul abs add Div NodeSep add dup + Cos mul exch Sin mul +} def +% +/TriNodePos { + Sin s lt + { d NodeSep sub dup Cos mul Sin Div exch } + { w h mul w Sin mul h Cos abs mul add Div + NodeSep add dup Cos mul exch Sin mul + } ifelse +} def +% +/InitTriNode { + sub 2 div exch + 2 div exch + 2 copy T + 2 copy 4 index index /d ED + pop pop pop pop + -90 mul rotate + /NodeMtrx CM def + /X 0 def /Y 0 def + d sub abs neg /d ED + d add /h ED + 2 div h mul h d sub Div /w ED + /s d w Atan sin def + /NodePos { TriNodePos } def +} def +% +/OvalNodePos { + /ww w NodeSep add def + /hh h NodeSep add def + Sin ww mul Cos hh mul Atan dup cos ww mul exch sin hh mul +} def +% +/GetCenter { begin X Y NodeMtrx transform CM itransform end } def +% +/XYPos { + dup sin exch cos Do + /Cos ED /Sin ED /Dist ED + Cos 0 gt + { Dist Dist Sin mul Cos div } + { Cos 0 lt + { Dist neg Dist Sin mul Cos div neg } + { 0 Dist Sin mul } ifelse + } ifelse + Do +} def +% +/GetEdge { + dup 0 eq + { pop begin 1 0 NodeMtrx dtransform + CM idtransform + exch atan sub + dup + sin /Sin ED + cos /Cos ED + /NodeSep ED + NodePos NodeMtrx dtransform CM idtransform end } + { 1 eq {{exch}} {{}} ifelse /Do ED pop XYPos } ifelse +} def +% +/AddOffset { + 1 index 0 eq + { pop pop } + { 2 copy 5 2 roll cos mul add 4 1 roll sin mul sub exch } ifelse +} def +% +/GetEdgeA { + NodeSepA AngleA NodeA NodeSepTypeA GetEdge + OffsetA AngleA AddOffset + yA add /yA1 ED + xA add /xA1 ED +} def +% +/GetEdgeB { + NodeSepB AngleB NodeB NodeSepTypeB GetEdge + OffsetB AngleB AddOffset + yB add /yB1 ED + xB add /xB1 ED +} def +% +/GetArmA { + ArmTypeA 0 eq + { /xA2 ArmA AngleA cos mul xA1 add def + /yA2 ArmA AngleA sin mul yA1 add def } + { ArmTypeA 1 eq {{exch}} {{}} ifelse + /Do ED + ArmA AngleA XYPos OffsetA AngleA AddOffset + yA add /yA2 ED + xA add /xA2 ED } ifelse +} def +% +/GetArmB { + ArmTypeB 0 eq + { /xB2 ArmB AngleB cos mul xB1 add def + /yB2 ArmB AngleB sin mul yB1 add def } + { ArmTypeB 1 eq {{exch}} {{}} ifelse + /Do ED + ArmB AngleB XYPos OffsetB AngleB AddOffset + yB add /yB2 ED + xB add /xB2 ED } ifelse +} def +% +/InitNC { + /b ED /a ED % second and first node + /NodeSepTypeB ED /NodeSepTypeA ED + /NodeSepB ED /NodeSepA ED + /OffsetB ED /OffsetA ED + tx@NodeDict a known tx@NodeDict b known and dup { + /NodeA a load def + /NodeB b load def + NodeA GetCenter /yA ED /xA ED + NodeB GetCenter /yB ED /xB ED } if +} def +% +/LPutLine { + 4 copy + 3 -1 roll sub neg 3 1 roll sub Atan /NAngle ED + 1 t sub mul + 3 1 roll 1 t sub mul + 4 1 roll t mul add /Y ED + t mul add /X ED +} def +% +/LPutLines { + mark LPutVar counttomark 2 div 1 sub /n ED +% t floor dup n gt + t floor dup n ge % to allow npos<= hv 2008-08-14 + { pop n 1 sub /t 1 def } { dup t sub neg /t ED } ifelse + cvi 2 mul { pop } repeat + LPutLine + cleartomark +} def +% +/BezierMidpoint { + /y3 ED /x3 ED /y2 ED /x2 ED /y1 ED /x1 ED /y0 ED /x0 ED /t ED + /cx x1 x0 sub 3 mul def + /cy y1 y0 sub 3 mul def + /bx x2 x1 sub 3 mul cx sub def + /by y2 y1 sub 3 mul cy sub def + /ax x3 x0 sub cx sub bx sub def + /ay y3 y0 sub cy sub by sub def + ax t 3 exp mul bx t t mul mul add + cx t mul add x0 add ay t 3 exp mul + by t t mul mul add cy t mul add + y0 add 3 ay t t mul mul mul 2 + by t mul mul add cy add 3 ax t t mul mul mul + 2 bx t mul mul add cx add atan /NAngle ED + /Y ED /X ED +} def +% +/HPosBegin { yB yA ge { /t 1 t sub def } if /Y yB yA sub t mul yA add def +} def +/HPosEnd { /X Y yyA sub yyB yyA sub Div xxB xxA sub mul xxA add def +/NAngle yyB yyA sub xxB xxA sub Atan def } def +/HPutLine { HPosBegin /yyA ED /xxA ED /yyB ED /xxB ED HPosEnd } def +/HPutLines { HPosBegin yB yA ge { /check { le } def } { /check { ge } def +} ifelse /xxA xA def /yyA yA def mark xB yB LPutVar { dup Y check { exit +} { /yyA ED /xxA ED } ifelse } loop /yyB ED /xxB ED cleartomark HPosEnd +} def +/VPosBegin { xB xA lt { /t 1 t sub def } if /X xB xA sub t mul xA add def +} def +/VPosEnd { /Y X xxA sub xxB xxA sub Div yyB yyA sub mul yyA add def +/NAngle yyB yyA sub xxB xxA sub Atan def } def +/VPutLine { VPosBegin /yyA ED /xxA ED /yyB ED /xxB ED VPosEnd } def +/VPutLines { VPosBegin xB xA ge { /check { le } def } { /check { ge } def +} ifelse /xxA xA def /yyA yA def mark xB yB LPutVar { 1 index X check { +exit } { /yyA ED /xxA ED } ifelse } loop /yyB ED /xxB ED cleartomark +VPosEnd } def +/HPutCurve { gsave newpath /SaveLPutVar /LPutVar load def LPutVar 8 -2 +roll moveto curveto flattenpath /LPutVar [ {} {} {} {} pathforall ] cvx +def grestore exec /LPutVar /SaveLPutVar load def } def +/NCCoor { /AngleA yB yA sub xB xA sub Atan def /AngleB AngleA 180 add def +GetEdgeA GetEdgeB /LPutVar [ xB1 yB1 xA1 yA1 ] cvx def /LPutPos { +LPutVar LPutLine } def /HPutPos { LPutVar HPutLine } def /VPutPos { +LPutVar VPutLine } def LPutVar } def +% +/NCLine { + NCCoor + tx@Dict begin + ArrowA CP 4 2 roll + ArrowB + lineto pop pop + end +} def +% +/NCLines { + false NArray + n 0 eq + { NCLine } + { 2 copy yA sub exch xA sub Atan /AngleA ED + n 2 mul dup index exch index yB sub exch xB sub + Atan /AngleB ED + GetEdgeA GetEdgeB + /LPutVar [ xB1 yB1 n 2 mul 4 add 4 roll xA1 yA1 ] cvx def + mark LPutVar + tx@Dict begin false Line end + /LPutPos { LPutLines } def + /HPutPos { HPutLines } def + /VPutPos { VPutLines } def + } ifelse +} def +% +/NCCurve { + GetEdgeA + GetEdgeB + xA1 xB1 sub yA1 yB1 sub Pyth 2 div dup 3 -1 +roll mul /ArmA ED mul /ArmB ED /ArmTypeA 0 def /ArmTypeB 0 def GetArmA +GetArmB xA2 yA2 xA1 yA1 tx@Dict begin ArrowA end xB2 yB2 xB1 yB1 tx@Dict +begin ArrowB end curveto /LPutVar [ xA1 yA1 xA2 yA2 xB2 yB2 xB1 yB1 ] +cvx def /LPutPos { t LPutVar BezierMidpoint } def /HPutPos { { HPutLines +} HPutCurve } def /VPutPos { { VPutLines } HPutCurve } def } def +% +/NCAngles { + GetEdgeA GetEdgeB GetArmA GetArmB + /mtrx AngleA matrix rotate def + xA2 yA2 mtrx transform pop + xB2 yB2 mtrx transform exch pop + mtrx itransform + /y0 ED /x0 ED + mark ArmB 0 ne { xB1 yB1 } if + xB2 yB2 x0 y0 xA2 yA2 + ArmA 0 ne { xA1 yA1 } if + tx@Dict begin false Line end + /LPutVar [ xB1 yB1 xB2 yB2 x0 y0 xA2 yA2 xA1 yA1 ] cvx def + /LPutPos { LPutLines } def + /HPutPos { HPutLines } def + /VPutPos { VPutLines } def } def +% +/NCAngle { + GetEdgeA GetEdgeB GetArmB + /mtrx AngleA matrix rotate def + xB2 yB2 mtrx itransform pop xA1 yA1 mtrx itransform exch pop mtrx transform + /y0 ED /x0 ED + mark + ArmB 0 ne { xB1 yB1 } if + xB2 yB2 x0 y0 xA1 yA1 + tx@Dict begin false Line end + /LPutVar [ xB1 yB1 xB2 yB2 x0 y0 xA1 yA1 ] cvx def + /LPutPos { LPutLines } def + /HPutPos { HPutLines } def + /VPutPos { VPutLines } def +} def +% +/NCBar { + GetEdgeA GetEdgeB GetArmA GetArmB + /mtrx AngleA matrix rotate def + xA2 yA2 mtrx itransform pop + xB2 yB2 mtrx itransform pop + sub dup 0 mtrx transform + 3 -1 roll 0 gt + { /yB2 exch yB2 add def /xB2 exch xB2 add def } + { /yA2 exch neg yA2 add def /xA2 exch neg xA2 add def } ifelse + mark + ArmB 0 ne { xB1 yB1 } if + xB2 yB2 xA2 yA2 ArmA 0 ne { xA1 yA1 } if + tx@Dict begin false Line end + /LPutVar [ xB1 yB1 xB2 yB2 xA2 yA2 xA1 yA1 ] cvx def + /LPutPos { LPutLines } def + /HPutPos { HPutLines } def + /VPutPos { VPutLines } def +} def +% +/NCDiag { + /lineAngle ED + GetEdgeA GetEdgeB GetArmA GetArmB mark + lineAngle abs 0 gt { + /xTemp xA2 10 add def + /yTemp yA2 lineAngle dup sin exch cos div 10 mul add def + /dY1 yTemp yA2 sub def + /dX1 xTemp xA2 sub def + /dY2 yB2 yB1 sub def + /dX2 xB2 xB1 sub def + dX1 abs 0.01 lt { + /m2 dY2 dX2 div def + /xB2 xA2 def + /yB2 xA2 xB1 sub m2 mul yB1 add def + }{ + dX2 abs 0.01 lt { + /m1 dY1 dX1 div def + /xB2 xB1 def + /yB2 xB1 xA2 sub m1 mul yA2 add def + }{% + /m1 dY1 dX1 div def + /m2 dY2 dX2 div def + /xB2 m1 xA2 mul m2 xB1 mul sub yA2 sub yB1 add m1 m2 sub div def + /yB2 xB2 xA2 sub m1 mul yA2 add def + } ifelse + } ifelse + } if + ArmB 0 ne { xB1 yB1 } if + xB2 yB2 xA2 yA2 + ArmA 0 ne { xA1 yA1 } if + tx@Dict begin false Line end + /LPutVar [ xB1 yB1 xB2 yB2 xA2 yA2 xA1 yA1 ] cvx def + /LPutPos { LPutLines } def + /HPutPos { HPutLines } def + /VPutPos { VPutLines } def +% +% GetEdgeA GetEdgeB GetArmA GetArmB mark +% ArmB 0 ne { xB1 yB1 } if +% xB2 yB2 xA2 yA2 +% ArmA 0 ne { xA1 yA1 } if +% tx@Dict begin false Line end +% /LPutVar [ xB1 yB1 xB2 yB2 xA2 yA2 xA1 yA1 ] cvx def +% /LPutPos { LPutLines } def +% /HPutPos { HPutLines } def +% /VPutPos { VPutLines } def +} def +% +/NCDiagg { + /lineAngle ED + GetEdgeA GetArmA + lineAngle abs 0 gt + { lineAngle } + { yB yA2 sub xB xA2 sub Atan 180 add } ifelse + /AngleB ED + GetEdgeB mark + lineAngle abs 0 gt { + /dY2 yA2 yA1 sub def + /dX2 xA2 xA1 sub def + lineAngle abs 90 eq { + /m2 dY2 dX2 div def + /yA2 xB xA2 sub m2 mul yA2 add def + /xA2 xB def + }{ + /m1 lineAngle dup sin exch cos div def % tan alpha + dX2 abs 0.01 lt { + /yA2 xA1 xB sub m1 mul yB add def + /xA2 xA1 def + }{% + /m2 dY2 dX2 div def + /xA2 m1 xB mul m2 xA2 mul sub yA2 add yB sub m1 m2 sub div def + /yA2 xA2 xB sub m1 mul yB add def + } ifelse + } ifelse + } if + xB1 yB1 xA2 yA2 + ArmA 0 ne { xA1 yA1 } if + tx@Dict begin false Line end + /LPutVar [ xB1 yB1 xA2 yA2 xA1 yA1 ] cvx def + /LPutPos { LPutLines } def + /HPutPos { HPutLines } def + /VPutPos { VPutLines } def +% +% GetEdgeA GetArmA +% yB yA2 sub xB xA2 sub Atan 180 add /AngleB ED +% GetEdgeB +% mark +% xB1 yB1 xA2 yA2 +% ArmA 0 ne { xA1 yA1 } if +% tx@Dict begin false Line end +% /LPutVar [ xB1 yB1 xA2 yA2 xA1 yA1 ] cvx def +% /LPutPos { LPutLines } def +% /HPutPos { HPutLines } def +% /VPutPos { VPutLines } def +} def +% +/NCLoop { + GetEdgeA GetEdgeB GetArmA GetArmB + /mtrx AngleA matrix rotate def + xA2 yA2 mtrx transform loopsize add /yA3 ED /xA3 ED + /xB3 xB2 yB2 mtrx transform pop def + xB3 yA3 mtrx itransform /yB3 ED /xB3 ED + xA3 yA3 mtrx itransform /yA3 ED /xA3 ED + mark ArmB 0 ne { xB1 yB1 } if + xB2 yB2 xB3 yB3 xA3 yA3 xA2 yA2 ArmA 0 ne { xA1 yA1 } if + tx@Dict begin false Line end + /LPutVar [ xB1 yB1 xB2 yB2 xB3 yB3 xA3 yA3 xA2 yA2 xA1 yA1 ] cvx def + /LPutPos { LPutLines } def + /HPutPos { HPutLines } def + /VPutPos { VPutLines } def +} def +% +% DG/SR modification begin - May 9, 1997 - Patch 1 +%/NCCircle { 0 0 NodesepA nodeA \tx@GetEdge pop xA sub 2 div dup 2 exp r +%r mul sub abs sqrt atan 2 mul /a ED r AngleA 90 add PtoC yA add exch xA add +%exch 2 copy /LPutVar [ 4 2 roll r AngleA ] cvx def /LPutPos { LPutVar t 360 +%mul add dup 5 1 roll 90 sub \tx@PtoC 3 -1 roll add /Y ED add /X ED /NAngle ED +% +/NCCircle { + NodeSepA 0 NodeA 0 GetEdge pop + 2 div dup 2 exp r r mul sub abs sqrt + atan 2 mul /a ED + r AngleA 90 add PtoC yA add exch xA add + exch 2 copy + /LPutVar [ 4 2 roll r AngleA ] cvx def + /LPutPos { + LPutVar t 360 mul add dup 5 1 roll 90 sub PtoC + 3 -1 roll add + /Y ED add /X ED /NAngle ED +% DG/SR modification end + } def + /HPutPos { LPutPos } def + /VPutPos { LPutPos } def + r AngleA 90 sub a add AngleA 270 add a sub + tx@Dict begin + /angleB ED /angleA ED /r ED + /c 57.2957 r Div def + /y ED /x ED +} def +% +/NCBox { + /d ED /h ED + /AngleB yB yA sub xB xA sub Atan def + /AngleA AngleB 180 add def + GetEdgeA GetEdgeB + /dx d AngleB sin mul def + /dy d AngleB cos mul neg def + /hx h AngleB sin mul neg def + /hy h AngleB cos mul def + /LPutVar [ + xA1 hx add yA1 hy add xB1 hx add yB1 hy add + xB1 dx add yB1 dy add xA1 dx add yA1 dy add ] cvx def + /LPutPos { LPutLines } def + /HPutPos { xB yB xA yA LPutLine } def + /VPutPos { HPutPos } def + mark + LPutVar tx@Dict begin false Polygon end +} def +% +/NCArcBox { + /l ED neg /d ED /h ED /a ED + /AngleA yB yA sub xB xA sub Atan def + /AngleB AngleA 180 add def + /tA AngleA a sub 90 add def + /tB tA a 2 mul add def + /r xB xA sub tA cos tB cos sub Div dup 0 eq { pop 1 } if def + /x0 xA r tA cos mul add def + /y0 yA r tA sin mul add def + /c 57.2958 r div def + /AngleA AngleA a sub 180 add def + /AngleB AngleB a add 180 add def + GetEdgeA GetEdgeB + /AngleA tA 180 add yA yA1 sub xA xA1 sub Pyth c mul sub def + /AngleB tB 180 add yB yB1 sub xB xB1 sub Pyth c mul add def + l 0 eq { + x0 y0 r h add AngleA AngleB arc x0 y0 r d add AngleB AngleA arcn + }{ + x0 y0 translate + /tA AngleA l c mul add def + /tB AngleB l c mul sub def + 0 0 r h add tA tB arc r h add + AngleB PtoC r d add + AngleB PtoC 2 copy + 6 2 roll l arcto 4 { pop } repeat + r d add tB PtoC l arcto 4 { pop } repeat + 0 0 r d add tB tA arcn r d add + AngleA PtoC r h add + AngleA PtoC 2 copy 6 2 roll + l arcto 4 { pop } repeat + r h add tA PtoC l arcto 4 { pop } repeat + } ifelse + closepath + /LPutVar [ x0 y0 r AngleA AngleB h d ] cvx def + /LPutPos { + LPutVar /d ED /h ED + /AngleB ED /AngleA ED + /r ED /y0 ED /x0 ED + t 1 le { + r h add AngleA 1 t sub mul AngleB t mul add dup 90 add /NAngle ED PtoC + }{t 2 lt { + /NAngle AngleB 180 add def r 2 t sub + h mul t 1 sub d mul add add AngleB PtoC + }{ + t 3 lt { + r d add AngleB 3 t sub mul AngleA 2 t sub + mul add dup 90 sub /NAngle ED PtoC + }{ + /NAngle AngleA 180 add def + r 4 t sub d mul t 3 sub h mul add add AngleA PtoC + } ifelse + } ifelse + } ifelse + y0 add /Y ED x0 add /X ED + } def + /HPutPos { LPutPos } def + /VPutPos { LPutPos } def +} def +% +/Tfan { /AngleA yB yA sub xB xA sub Atan def GetEdgeA w xA1 xB sub yA1 yB +sub Pyth Pyth w Div CLW 2 div mul 2 div dup AngleA sin mul yA1 add /yA1 +ED AngleA cos mul xA1 add /xA1 ED /LPutVar [ xA1 yA1 m { xB w add yB xB +w sub yB } { xB yB w sub xB yB w add } ifelse xA1 yA1 ] cvx def /LPutPos +{ LPutLines } def /VPutPos@ { LPutVar flag { 8 4 roll pop pop pop pop } +{ pop pop pop pop 4 2 roll } ifelse } def /VPutPos { VPutPos@ VPutLine } +def /HPutPos { VPutPos@ HPutLine } def mark LPutVar tx@Dict begin +/ArrowA { moveto } def /ArrowB { } def false Line closepath end } def +% +/LPutCoor { + NAngle + tx@Dict begin /NAngle ED end + gsave + CM STV + CP Y sub neg exch X sub neg exch moveto + setmatrix CP + grestore +} def +% +/LPut { + tx@NodeDict /LPutPos known + { LPutPos } { CP /Y ED /X ED /NAngle 0 def } ifelse + LPutCoor +} def +% +/HPutAdjust { + Sin Cos mul 0 eq + { 0 } + { d Cos mul Sin div flag not { neg } if + h Cos mul Sin div flag { neg } if + 2 copy gt { pop } { exch pop } ifelse + } ifelse + s add flag { r add neg }{ l add } ifelse + X add /X ED +} def +% +/VPutAdjust { + Sin Cos mul + 0 eq + { 0 } + { l Sin mul Cos div flag { neg } if + r Sin mul Cos div flag not { neg } if + 2 copy gt { pop } { exch pop } ifelse + } ifelse + s add flag { d add } { h add neg } ifelse + Y add /Y ED +} def +% +% +end +% +% END pst-node.pro + +%%EndProcSet +%%BeginProcSet: 8r.enc 0 0 +% File 8r.enc TeX Base 1 Encoding Revision 2.0 2002-10-30 +% +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry, +% W. Schmidt, P. Lehman", +% version = "2.0", +% date = "27nov06", +% filename = "8r.enc", +% email = "tex-fonts@@tug.org", +% docstring = "This is the encoding vector for Type1 and TrueType +% fonts to be used with TeX. This file is part of the +% PSNFSS bundle, version 9" +% @} +% +% The idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard encoding, ISO Latin 1, Windows ANSI including the euro symbol, +% MacRoman, and some extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% These are /dotlessj /ff /ffi /ffl. +% +% (4) hyphen appears twice for compatibility with both ASCII and Windows. +% +% (5) /Euro was assigned to 128, as in Windows ANSI +% +% (6) Missing characters from MacRoman encoding incorporated as follows: +% +% PostScript MacRoman TeXBase1 +% -------------- -------------- -------------- +% /notequal 173 0x16 +% /infinity 176 0x17 +% /lessequal 178 0x18 +% /greaterequal 179 0x19 +% /partialdiff 182 0x1A +% /summation 183 0x1B +% /product 184 0x1C +% /pi 185 0x1D +% /integral 186 0x81 +% /Omega 189 0x8D +% /radical 195 0x8E +% /approxequal 197 0x8F +% /Delta 198 0x9D +% /lozenge 215 0x9E +% +/TeXBase1Encoding [ +% 0x00 + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef /breve + /minus /.notdef /Zcaron /zcaron +% 0x10 + /caron /dotlessi /dotlessj /ff + /ffi /ffl /notequal /infinity + /lessequal /greaterequal /partialdiff /summation + /product /pi /grave /quotesingle +% 0x20 + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus + /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three + /four /five /six /seven + /eight /nine /colon /semicolon + /less /equal /greater /question +% 0x40 + /at /A /B /C + /D /E /F /G + /H /I /J /K + /L /M /N /O +% 0x50 + /P /Q /R /S + /T /U /V /W + /X /Y /Z /bracketleft + /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c + /d /e /f /g + /h /i /j /k + /l /m /n /o +% 0x70 + /p /q /r /s + /t /u /v /w + /x /y /z /braceleft + /bar /braceright /asciitilde /.notdef +% 0x80 + /Euro /integral /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /Omega /radical /approxequal +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /Delta /lozenge /Ydieresis +% 0xA0 + /.notdef /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot /hyphen /registered /macron +% 0xB0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde + /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + + +%%EndProcSet +%%BeginProcSet: texps.pro 0 0 +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]FontType 0 +ne{/Metrics exch def dict begin Encoding{exch dup type/integertype ne{ +pop pop 1 sub dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get +div def}ifelse}forall Metrics/Metrics currentdict end def}{{1 index type +/nametype eq{exit}if exch pop}loop}ifelse[2 index currentdict end +definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{dup +sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 roll +mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def dup[ +exch{dup CharStrings exch known not{pop/.notdef/Encoding true def}if} +forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def}def +end + +%%EndProcSet +%%BeginProcSet: special.pro 0 0 +%! +TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N +/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known +{userdict/md get type/dicttype eq{userdict begin md length 10 add md +maxlength ge{/md md dup length 20 add dict copy def}if end md begin +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState +save N userdict maxlength dict begin/magscale true def normalscale +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub +TR/showpage{}N/erasepage{}N/setpagedevice{pop}N/copypage{}N/p 3 def +@MacSetUp}N/doclip{psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll +newpath 4 copy 4 2 roll moveto 6 -1 roll S lineto S lineto S lineto +closepath clip newpath moveto}N/endTexFig{end psf$SavedState restore}N +/@beginspecial{SDict begin/SpecialSave save N gsave normalscale +currentpoint TR @SpecialDefaults count/ocount X/dcount countdictstack N} +N/@setspecial{CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs +neg 0 rlineto closepath clip}if ho vo TR hsc vsc scale ang rotate +rwiSeen{rwi urx llx sub div rhiSeen{rhi ury lly sub div}{dup}ifelse +scale llx neg lly neg TR}{rhiSeen{rhi ury lly sub div dup scale llx neg +lly neg TR}if}ifelse CLIP 2 eq{newpath llx lly moveto urx lly lineto urx +ury lineto llx ury lineto closepath clip}if/showpage{}N/erasepage{}N +/setpagedevice{pop}N/copypage{}N newpath}N/@endspecial{count ocount sub{ +pop}repeat countdictstack dcount sub{end}repeat grestore SpecialSave +restore end}N/@defspecial{SDict begin}N/@fedspecial{end}B/li{lineto}B +/rl{rlineto}B/rc{rcurveto}B/np{/SaveX currentpoint/SaveY X N 1 +setlinecap newpath}N/st{stroke SaveX SaveY moveto}N/fil{fill SaveX SaveY +moveto}N/ellipse{/endangle X/startangle X/yrad X/xrad X/savematrix +matrix currentmatrix N TR xrad yrad scale 0 0 1 startangle endangle arc +savematrix setmatrix}N end + +%%EndProcSet +%%BeginProcSet: color.pro 0 0 +%! +TeXDict begin/setcmykcolor where{pop}{/setcmykcolor{dup 10 eq{pop +setrgbcolor}{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll +}repeat setrgbcolor pop}ifelse}B}ifelse/TeXcolorcmyk{setcmykcolor}def +/TeXcolorrgb{setrgbcolor}def/TeXcolorgrey{setgray}def/TeXcolorgray{ +setgray}def/TeXcolorhsb{sethsbcolor}def/currentcmykcolor where{pop}{ +/currentcmykcolor{currentrgbcolor 10}B}ifelse/DC{exch dup userdict exch +known{pop pop}{X}ifelse}B/GreenYellow{0.15 0 0.69 0 setcmykcolor}DC +/Yellow{0 0 1 0 setcmykcolor}DC/Goldenrod{0 0.10 0.84 0 setcmykcolor}DC +/Dandelion{0 0.29 0.84 0 setcmykcolor}DC/Apricot{0 0.32 0.52 0 +setcmykcolor}DC/Peach{0 0.50 0.70 0 setcmykcolor}DC/Melon{0 0.46 0.50 0 +setcmykcolor}DC/YellowOrange{0 0.42 1 0 setcmykcolor}DC/Orange{0 0.61 +0.87 0 setcmykcolor}DC/BurntOrange{0 0.51 1 0 setcmykcolor}DC +/Bittersweet{0 0.75 1 0.24 setcmykcolor}DC/RedOrange{0 0.77 0.87 0 +setcmykcolor}DC/Mahogany{0 0.85 0.87 0.35 setcmykcolor}DC/Maroon{0 0.87 +0.68 0.32 setcmykcolor}DC/BrickRed{0 0.89 0.94 0.28 setcmykcolor}DC/Red{ +0 1 1 0 setcmykcolor}DC/OrangeRed{0 1 0.50 0 setcmykcolor}DC/RubineRed{ +0 1 0.13 0 setcmykcolor}DC/WildStrawberry{0 0.96 0.39 0 setcmykcolor}DC +/Salmon{0 0.53 0.38 0 setcmykcolor}DC/CarnationPink{0 0.63 0 0 +setcmykcolor}DC/Magenta{0 1 0 0 setcmykcolor}DC/VioletRed{0 0.81 0 0 +setcmykcolor}DC/Rhodamine{0 0.82 0 0 setcmykcolor}DC/Mulberry{0.34 0.90 +0 0.02 setcmykcolor}DC/RedViolet{0.07 0.90 0 0.34 setcmykcolor}DC +/Fuchsia{0.47 0.91 0 0.08 setcmykcolor}DC/Lavender{0 0.48 0 0 +setcmykcolor}DC/Thistle{0.12 0.59 0 0 setcmykcolor}DC/Orchid{0.32 0.64 0 +0 setcmykcolor}DC/DarkOrchid{0.40 0.80 0.20 0 setcmykcolor}DC/Purple{ +0.45 0.86 0 0 setcmykcolor}DC/Plum{0.50 1 0 0 setcmykcolor}DC/Violet{ +0.79 0.88 0 0 setcmykcolor}DC/RoyalPurple{0.75 0.90 0 0 setcmykcolor}DC +/BlueViolet{0.86 0.91 0 0.04 setcmykcolor}DC/Periwinkle{0.57 0.55 0 0 +setcmykcolor}DC/CadetBlue{0.62 0.57 0.23 0 setcmykcolor}DC +/CornflowerBlue{0.65 0.13 0 0 setcmykcolor}DC/MidnightBlue{0.98 0.13 0 +0.43 setcmykcolor}DC/NavyBlue{0.94 0.54 0 0 setcmykcolor}DC/RoyalBlue{1 +0.50 0 0 setcmykcolor}DC/Blue{1 1 0 0 setcmykcolor}DC/Cerulean{0.94 0.11 +0 0 setcmykcolor}DC/Cyan{1 0 0 0 setcmykcolor}DC/ProcessBlue{0.96 0 0 0 +setcmykcolor}DC/SkyBlue{0.62 0 0.12 0 setcmykcolor}DC/Turquoise{0.85 0 +0.20 0 setcmykcolor}DC/TealBlue{0.86 0 0.34 0.02 setcmykcolor}DC +/Aquamarine{0.82 0 0.30 0 setcmykcolor}DC/BlueGreen{0.85 0 0.33 0 +setcmykcolor}DC/Emerald{1 0 0.50 0 setcmykcolor}DC/JungleGreen{0.99 0 +0.52 0 setcmykcolor}DC/SeaGreen{0.69 0 0.50 0 setcmykcolor}DC/Green{1 0 +1 0 setcmykcolor}DC/ForestGreen{0.91 0 0.88 0.12 setcmykcolor}DC +/PineGreen{0.92 0 0.59 0.25 setcmykcolor}DC/LimeGreen{0.50 0 1 0 +setcmykcolor}DC/YellowGreen{0.44 0 0.74 0 setcmykcolor}DC/SpringGreen{ +0.26 0 0.76 0 setcmykcolor}DC/OliveGreen{0.64 0 0.95 0.40 setcmykcolor} +DC/RawSienna{0 0.72 1 0.45 setcmykcolor}DC/Sepia{0 0.83 1 0.70 +setcmykcolor}DC/Brown{0 0.81 1 0.60 setcmykcolor}DC/Tan{0.14 0.42 0.56 0 +setcmykcolor}DC/Gray{0 0 0 0.50 setcmykcolor}DC/Black{0 0 0 1 +setcmykcolor}DC/White{0 0 0 0 setcmykcolor}DC end + +%%EndProcSet +%%BeginFont: NimbusSanL-Regu +%!PS-AdobeFont-1.0: NimbusSanL-Regu 1.05a +%%Title: NimbusSanL-Regu +%%CreationDate: Thu Mar 20 10:08:51 2003 +%%Creator: Primoz Peterlin +%%DocumentSuppliedResources: font NimbusSanL-Regu +% Copyright (URW)++,Copyright 1999 by (URW)++ Design & Development +% Generated by PfaEdit 1.0 (http://pfaedit.sf.net/) +%%EndComments +FontDirectory/NimbusSanL-Regu known{/NimbusSanL-Regu findfont dup/UniqueID known{dup +/UniqueID get 5020902 eq exch/FontType get 1 eq and}{pop false}ifelse +{save true}{false}ifelse}{false}ifelse +11 dict begin +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0 ]readonly def +/FontName /NimbusSanL-Regu def +/FontBBox [-174 -285 1001 953 ]readonly def +/UniqueID 5020902 def +/PaintType 0 def +/FontInfo 9 dict dup begin +/version (1.05a) readonly def +/Notice (Copyright \050URW\051++,Copyright 1999 by \050URW\051++ Design & Development) readonly def +/FullName (Nimbus Sans L Regular) readonly def +/FamilyName (Nimbus Sans L) readonly def +/Weight (Regular) readonly def +/ItalicAngle 0 def +/isFixedPitch false def +/UnderlinePosition -151 def +/UnderlineThickness 50 def +end readonly def +/Encoding StandardEncoding def +currentdict end +currentfile eexec +D9D66F633B846AB284BCF8B0411B772DE5CE33C33655F6FF751F340A8D6C01E3 +2E02C24E186BA91B34A1F538959D4450CB683EAE5B034D030186901B458D3777 +6B3942BD2E07121385120248891AEC2EB33C4E3A0CF00828D0F130C31A918C18 +979FE94379C648EF21ABF659253E43CD1253866F157F1DF85AE7E8714F061B1E +ABA3AD094FE8D6293916FA82EE4F486C7E513A06D4C9BE44306A8287970B4ABF +B6D1F9274A5A0BB6ECF713ADBD1260D5D6C4420D357FD486470A74B2F0621B59 +A9373ABECDBF32FA68AABB66FAB0C970A3354A335D70DB2CC5A3208BB6D768E7 +B58CD9BC2B6B7E110693C5A88D680B7290DB121996E3B7C8AE3C23147280F8BF +D8C60B415552700FF0E44C2257B467ADD5D550F61EC34A76143393E0B34D55C0 +8B64B48E5F1FD16E16B967511AE15434B7F755BDF2574191E3C3DC528B69B5BA +7DDBBD3C7878FA69ADE75011A2C0F02F5707E86FA632D1269281D3C265B31F3B +F3145052467647AFE18B9D763FAEE4BA72CB9C385568EE5BBF5854C278F1E3CC +475C6234E83ED33345268BE52F0931B58F302EDA0D5751348E7B7E53D4882FB6 +9343BDAAE87E48F6E82024D8EC1FACBBA36582092CCD76553B0449A5090774EA +7242123C53B80F2E927B98DF2B36C403D1FA1E9F8439F3964DC9F89A0CAB5AE2 +C907309460F097AA87BD156575D6C73EDB2B40C015E67734397ED14395C43394 +7A0201C6B0F652B035FD7BB82ED236D0F7C20048AFD83A56925C7A2898B46270 +B440913E4714FD89697B3E59F5BDD5A2AACF6630257957ABE1A63502A3081B6E +307A534A9E238F986D4C866AFBAB7A0B1B5A6E99AA0A56DC1FD7E8A39CC45147 +259AC7033A0C58192CA82FB12E09F309F75690043646193AD92D2368F345771F +01CFD21236BA52F74E36CF4B94259CDBA2EF1D61AD93A2B942A9896B0819D20C +59E440851CB99E89C887FC62FD9E7F88F54E5BC157D81A5FBC70699820C51BC6 +27D7755B195C0BAD8225A6F3EAE0A5A674E8AF6B11BCC69DCF5FB89D8BE0E2E5 +FE7E2588F93F583E4E2F6ED5457E90B902B02F51D54B9F0BA54291E687F4A7A2 +08CA5FCE0C9F3B954247312EDA3C532D3DCDFDCB56FFE03B36DB7D549D4203C6 +7DA8772A2F732A15DE675D3212C28DC755E3D0156A777BF514112ABBE4372ACB +97D7834813E1850F90CEE543B4C09BE1E93742EA98B8CACC09FCC4D2595EECD4 +46C942EEA60211FA7DBC11CE869D55BF0C7EC6AA747EB2AE2CB3CC2DBEC936C9 +540CE2E08291323B36F6549CDB97BBF9F0DA429CA9C863B629410885540DA6C4 +9AAADB30C39051C993CB547BCD573D6448DC09BF7FF2D1B108ABEC2AAEE4060D +182ABDB3100AC627E5C883E8F42D90D699C8028D4123472F211C8FBB744D7E3D +C626ED03D8517D69E1ACD26BE4F83FAE31122294816736827D138E4F4CAB1681 +236C1654E01231EA7F08AD0E73BBE1BE19A7AD6DA63AE0C7F5A360A53BB35268 +CC90125C7545D9D59F5127F0AD964AA66DF020F639832FAF9C2CCA82C01120BA +6469960C350D3AF786666EC14158728E0BA2DD8A639C28E0A7EA8BBF608FD7DF +79C7B5DDEA05C8C3D6FC70177D1A9EA9AD056F0CE31AB535A22FF7EB3374807A +AA630030F4833B3733610842E52E2701462693C39189C7BAC7D7888CF1CA106E +570C1223A5763651EEF6D32811F076030FFF4160369637180C9898BA219179F9 +CFBC0375AA8CBD963108618C5DF6DAA0231FE1FC8F053390E2ED53A02AC552A2 +130FBBB4015D583E77591E3F95B91589521F9258497A663C1BD44883364A43F4 +004F42E4E32F2AD8BB9DAC4D110FF47A42D923C153F7A83BC1FFE67CD11FF1A0 +9086B2FF0BBA147BFF00785663883D258292F85977CF1700323489C7DFEB4B7A +F909F18A9D03092B60BCD025878AC44DB91F33D815AC9DC3F442979BFA0C776B +5F6027EA3FD56E6B640D8A374385274046CB7232023DFC1D7D4C4FAF55E151C3 +9FEF8B47E0025EBB8C18BE053CEE561076BF062F476691EDAA1A8B0E33B06E3D +F0CA28D9626A7DEEE92DF84CF5967A74F27B2378201CE997FFE0C8F20AA9E7FE +C21B4E9DC8D21EE48F9FC2C35D851EE98AD3863A0A6C40428A32B2464C87E51D +C00983F964BE9851244F76C015850233274256B42EC01BA2C8189D5556B71345 +AC51F801C9965C87B89B8C1DB7526B19F7F0C20B11FDB0F2C2A9B7B8DD2F0B8D +82752DF19FF85F3ABBCA8FA903A11C3DC43E4C2E379C5976ADA0586431588D2E +791152651C251B9EB5A26DEF9EFA45B44CC4377562BCFF8E6351E76E7DB866A2 +DB1B877D064467A00156D51C3EF8E085B2FD09344F3BF4A730E275AD19B4C843 +79284AE28059F269B6B1980DE8C189E8D4AAE2283D802BD33940F2301579118E +B3FE1F74698D6A2A4388877008041A3D43118ED30D3D9000A6AA1F71D6CC6FF0 +54657F8F56BE5DD221F4E05D8C864F9DD3E99FF860365B9C030A2182FA8F453B +B48A71F8C0078A809559DCD512143D7930DFA19796F33162E64169C043FFACE0 +D9A0827E85477A26F6FF812CE452F8BA4FE15BE07CF0A0BCCC8416817C800C17 +2BF0F2B6418DE6EA6A89CAF0517858C28A24FC4BB6CC825318CD72FBBF942797 +B520E7863060555EE34D0CFF21E2CBDE1D3BD3710A1EBBE6AFF31D39046A3498 +21ED5592A38CEF96C847C26CD1CACB9F09C9B3FDE7D42F07494E52C4BB7A8C1A +5B73CAF825FE6D23C672FD62737C3CE3729076C195FCE6854C1B7F8143F95121 +0E0C4BEEFA8FDFF217A5C564C26AF208A998D9EB904C01934466E3467C33500D +A5759D88CA1552371F182854DAA7B524280129AEDEB5F6A2C23B7B2943CE5928 +3054AA61D40A0CBEFB7D50D3367E37A26457974F9528D81E21C743D7912BA628 +ED2C5458AED855E5CF47D804E9A2F18556302CC69B58805E1951CBF236F05AE5 +48571F98C01BF41ACD72D8396DEAE2CA1995945D1ECD86A85FBAD4D93CF6DEE2 +85AFC8179AAC6830D19D19CB2F9731732285757CA11233A368C666168D45B8D2 +7B5956598CBA113C18825686F9ED9588F06261AF3E8D1343D4971863ECE4DDE1 +1AA3604E2022AFC909284A4D43B5CBDAC5361A8898FBD82502DB93C42AEB42D4 +3FFD27DF5BE4E6F286D27D731EE30D4871387A7476DAE2F97FD20A0D927FD311 +267BB33D43183649CEA500A10CA5AA4B92B0A965BEA31B1EC7035C2A626853C9 +0F5B8CECEC977F9C78F5BB09727EBC06D1830262FBD406E48C8107A98B612A4B +C3C2E8B2504E0CA6E7B65FE8DFBEDBE6F43F03DE472E51A17BE5E15126B33BF5 +AA4257DEB8FEA60D5D46F43FBD58B88F8C80CB0D5520FE93222659DB735F2A29 +3159AD84AF082B956F1452EDC54D8652DAAC725D06E4441F403A9D105E4738D2 +762173BE413C71765E586A1A44663813D94E02A669B9D1A16E9E60C07909D06D +055FA464D3C8B1E65889BD71890B36BD310D1A184C084913958D22575E85FE85 +929418AB684A92B4187DBA74B626F82379048B124D8CC7A4AFBB516DABB82503 +272023C7822BE402583DD54376DEDD8CB84534728EE8FE26808EA08264BA5B60 +C89EBDDDED2D74AE20D4B29604D021B8CB1F3AD649346C3079B29055B18C8579 +95ABABB9715C492F6893DFF6C5C708439E4EEAE16EED2627A072AAF76D3E3E23 +764E9A5DBE640CA98585DA2A4AF9DE5A50410174D9096CE251AB40E97F9CED60 +2D05F6835AA84E7E676183ABBE7DAEF97170046518FF27E67EEE2AAD88AE9526 +C39853101B9461F4C1862A4534F300477BA9712E3305DE9A02A8B5684BEF87D9 +D231C885FC00409D78D26D45BEE77B40CEE6E191449727385DBF1135429CC8E4 +162D346EEDC7260000BBF6A73BCE98B8C80115898F910F38FD25CE03F740C969 +FCD8FC608210AA84D69CE8C6203A71CB424C72AF75C1818F6A1AA2D6F0366171 +9C67527EB25CCD9328283C9F0A171A78199029B3C52A85E3A069D5265B78DF1E +8A68FD311B9135C70CD0214CF04A4EC5AD120D492F25CD6E18D36ED71F266282 +6D9A1865668783704E8026D233E830FA696DA3480C857B7E2F12318F34862A3C +E07B5DD50A9FC1F5DAE96E1A7A9C6023DE05228EC140AFB41C532DE5BF0DA704 +808D7B0878A09BF1DCA7218548DD629E4877DC526ACBDE6CC483A11B60938F09 +56B761B72719C1AD14481B2B5150C63198D61A3611651ED85BB69B7607279862 +E41917DA08F87D352652A3C3B996AEE312CB054E84BD3442D366CC01BEDD930B +212F7629286D48D6529E15ADC93E621833FC3E9046979CC6484CD39D18A81F73 +89979EF408D778E57338E1C0861E8C7BFA5F6CB780E69545567B2D7D0891B235 +3175C1F2DA4318DB4204677B4C30652DA10155F9CD902439E4C277543DBF8863 +B5913AC7450A9D8EF1AA36E0FEBD0355B1EB79A6754351E6D44DB13FEDFFC046 +586EB8FA93C30F0F6C56F65692AF6300EDDD7C6222E5E6C4C2F7FF76F2D3BD13 +5777FEB9EA676D3DA2CFF1FE837AFA5ACB690E4D0D37AC4364DA7A652950C137 +A81742E0862B9955F2907E896EC55DDED158758A566E6FBAB579FFFED4E986A0 +5368E6A963B3CBDE11FA38B2E505E056DA9F17C7F0E48D1A5785DC7B9054F72F +2B592F3AC64092E57A292406C77088C92872E8EE1D792693B636273D8190E935 +0F00387FC9A85AD02DB3814D80F5D9C8FAFD218337C59D0FAAE063DE3EF1D2DA +BC95F18B94B223705392AECB2D320E62E4963CD30B916B68585D86F89D8A0208 +30A9D2D9E60B8C5BD09BD3EDA8FB9688695880DE138049C72B35D3F0056591AF +DAC907F2CF78FD366BF903956AC15542F2FBF876937837974D5652CBD628B4B0 +9AE4668E35ABEEA8E3DFC2CB367DBEA16F792CE90B7B3D7C328B67483082AAA6 +992EEA386BAA6EA401123DBE1C5335B77FA45F075C493BDE26B484535C829D8E +BB0F205E94C6B10760D917A9872422E961402B8F0BB1D344A25A23FBAB18AED0 +84DC893D3B277DC959082D6B0AB756FFFEDF6893BD0D8EB23CE515ED95C6A27E +285A6E621D9D35D749B505B89BD943B9BE5DB98F34573B30DC09FDC8836754FE +CB55303C0F56D096F290FF27F728755AF273FD17CB441267056C7E44E9299CB9 +F18FA481409D4236F9C0457791CC98ACD13729963B6ADD2307E46DBCECB40278 +56C5D090116E732EB0402288BFA396FF13266915B2749BE131715021A9B52922 +CF041978B01E0DBF8437BEF05E41743098955DB5D3C4D8FAC40123EEE8EB2014 +95E43826616D6D09661E61E8C28C2A9BEAEDB47CD27530A7EB000A89CE791B94 +F6CD2C0445D4A7B52DE6F74DD4C7BBD126A14EBC7480A39847C948870B63C29D +B2F47EFFF9E44206162A2C1DEF1D82F9386D2206B8242946377F6BB6B7E1AE61 +9CB959B14DCB62457465D757C9E0A4E45CB5723C36C7B004D8DAB6129BD4CE26 +3A8EF8385BB22320DC841B57CCD2C0EF209C19D095C4B29A3CC8A709D989DC23 +92630A5665A0720927A45893CCF99820569196F4A64EDF0BE67A402F2872117C +F19E9A26CCEF248446E02763D4C3DCD7DC0DAF59C36EDD282FF13EB4D8A357B0 +9C54DD9282A1EB310DB9028FCA6E39F01AE0EA0ED503C3535B3E98A009FD0801 +CAB7F0413DBF5DC2815EBD716031898ECEF7B0B01E1BFFFD8303115F95591AF9 +12946BC48A3737A429CB6500C76020A52228BCDDC200F7C23547A4C25150BB42 +7F1BD4092FF9B42BEFA53BE3FD3B9C5750276E21F36115B756F8B9784E9865AE +A669F8339785EE3B0E7462D73FF2602148EAC2FC9C4CC1CBCF99D24F0A6875DE +6049B6CE3E6A1314D70796217FCC42BF739A36BDB9EA9F474726C10E26AF7610 +4B7F0FF8688BDD39725D13B1758E541A7CEBE11846693EA006D3F1B42E4D2CB3 +2B05FB6A16E9510C28EA927D0E229ECA81226564AB1FC6F43B3E79088E8F71AD +230744A368F01EB074FF801AF4726D23958B222DF2F09481AB79441AB82DFFD5 +52E7B9BC49589F776D5F7384D4B8E57BFA9CF9109159CF9C195C297DF32C79C6 +D7C50E74A30FED2E2F2396C1B85A89645802D3656244EC8B94A7C1DD1FDBC039 +B8F18EE9CC7BB07F3A4D8D05F49D140B74B18054C0DAC7C04ED564AF28EDD217 +23F74173D182F6AFE9FE68F59C4CDE8847059BF7EAA032E878F96D8C47832FC3 +014E096E7A10DABBABF4D98CCC56C3949FF999F78E51847C8956A6EA0D710A64 +CE6A13DA51425E430059B69E9CB87D68677D2E9C8E863BD6ABBA293BE8C91A17 +310B141ED7D2607877213B9C635298398E35E5209302AA02F81FE55F3C2D3880 +A49E552B8AADAB5376F8CA0B9D921BD9ACE077E8C4508990EBAA1596F9BDDB9F +980A82DD4C575AAB977CF26ED4EFB2CD00BA88B4AE713E73BA044F2B8DFEF36A +FFA14EF17C45AE1B0402D886E63B995487527D31760BEEEB447EB37A90A85C16 +0BB5E90A3CC82AB93F765606366123205DAD4AF54566AC3BE76C898C89C4E8FE +71C8F6AD7194D598226F6EA941CAD1BA66E33FB868227DCFE080A9DEC9715E25 +8A592011CC9FBD69CEE9162A030C220AC4FC2BDAA16966E02FE7C45A956828FA +71BA15AF1E1BFB18C94A524DE324A877E445849674DDF11FCBE8444131E4EB37 +3733FFA84F4FAF02D34AAD7114CE5FB47685A93537B04CD214C3825A8EC8071E +D13C3F5DA22C8DBFB3A109704EEF23C5F071A88FE018D4AC09006E063E8F0703 +D2BA9736587F17127E10C48ABA249E6AC0B89904AD0B52E23D44D997108EA249 +5ADE3DD6E9E161A94D2AF180127C7EC27983CAD060232436100AF1CFEB7BFA36 +6F96ADF4EA2C6830EF90E84E17B0752CB69DE39232F597F5A83AD05A6D8540C8 +CFD74B53563F7E8EDC653414FCD3E1B5A84D6DF03B3406874EEBC6B70AECFCE4 +FEE508946C97268629949DCAD15CE4ABDF4555310615D6D87948B0A991A5C9E7 +4ADCB0658870A790D10C7A2B78051E5E2E08D7722AF9C5E2BC17F5A603BE0A8E +FF72EFA7ECF54CA0ABC35D9F43D84818D2F3894483E8086C002255701FCA5E4C +4234FC3BCBCD05007118EA17328BB3CEE6F6D2E206DC631E158F65C8206660B9 +D7DDEDC049527ED6E1729F92E2DA1E72246F2B09E01BE4B7F185DAF6BA5DB534 +E8CE6FF775F8AEC554F4049D70C903DA051D51718AAF9D4325E087D0C53BB8D2 +5A0CEB606B959F28A26A782C07E218AA30DEB661C9D4FF69CA67C2D061FADE56 +FC58C23689D64FDC9554856D12B2057EEFFC512AF0843CB049CF719836384099 +DC1BC3E01C38829A62DF2CBA2F8D1EDE33B06E8C97D1248E21A53B4E2FCF7A18 +98DD9B02360035AD49D6E4A9FB766DF20DE91E5F299D1C5533A260BC72A9C11B +3D0818C1432F722EF5F2278479C878BC697EADCC199CCE2A09100847A7755A8E +42A86DEE7946F3B130A8AA77B28DD289A827447BCEBC71F71586FDFD21CF4EB4 +31462D992759D67BAC9A6CE940489CFB72E116DD648268219B9B2525A3742EF7 +BDB4EACDFB96A16AF654F04AFE98FB3D269EFE817C3D4FED2D7B3BEE77442E8D +35F0250933FABC1CE2FC9986AFC2131062B0ED6AB55D708E660525174537CD1E +877FD540C203CD34DBF27FEE0F23B9B46B0720888637E886F56A72ACE4D775DA +F8A8EAC596F92754B2DE91132E36ED6B862837259F1430DC8A02261BDF7AEAFA +6770F25A8012B4563140CF9252E71EAB5CE8BBFEACE7A956D545F0C6370CF388 +43B72A05CE22B25BE80AE9DA50D84FC608046EF7407BF46A70F8C746E7355B99 +DDF85DDEBFD66722B14D390BED35A2CEC9E1B79BBB8E43361157494F032A932E +596962EC3A073C75D0AA71538E69B6B120ADD698868C415F78374CABFAA0A185 +5B18C7 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark +{restore}if +%%EndFont +TeXDict begin 40258437 52099154 1000 1200 1200 +(io-ports-and-interrupts.dvi) +@start /Fa 27[92 105[83 1[83 2[92 46 83 55 1[92 92 92 +1[37 2[37 92 1[46 92 1[83 92 92 16[111 129 5[46 1[129 +25[55 45[{ TeXBase1Encoding ReEncodeFont }23 166.044 +/NimbusSanL-Regu rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 1200dpi +TeXDict begin + end +%%EndSetup +TeXDict begin 1 0 bop 0 TeXcolorgray Black 1029 880 a +tx@Dict begin gsave STV CP T /ps@rot 0 def grestore end + +1029 880 a 1029 880 a +tx@Dict begin gsave STV CP T /ps@refangle 0. def grestore end + 1029 880 a 0 TeXcolorgray 1029 +880 a +tx@Dict begin gsave STV CP T /ps@rot 0 def grestore end + 1029 880 a 1279 3715 a +tx@Dict begin { 0.0 0.0 } PutCoor PutBegin end + 1279 3715 a @beginspecial +@setspecial + tx@Dict begin STP newpath /ArrowA { moveto } def /ArrowB { } def + 0.8 SLW 0 setgray 0.25 true 0.0 0.0 56.90549 142.26372 .5 Frame + gsave 0.8 SLW 0 setgray 1. .setopacityalpha 0 setlinejoin 0 +setlinecap stroke grestore end + +@endspecial 1279 3715 a +tx@Dict begin PutEnd end + 1279 3715 a 1279 +3715 a +tx@Dict begin { 28.45274 128.03734 } PutCoor PutBegin end + 1279 3715 a 906 3833 a Fa(Proz)n(essor)1279 3715 +y +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin { 56.90549 105.27505 } PutCoor PutBegin end + 1279 3715 a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@p0 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 +3715 a 1279 3715 a +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin { 56.90549 93.89413 } PutCoor PutBegin end + 1279 3715 +a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@q0 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 3715 a 1279 3715 a +tx@Dict begin PutEnd end + 1279 3715 a 1279 +3715 a +tx@Dict begin { 56.90549 28.45274 } PutCoor PutBegin end + 1279 3715 a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@i0 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 3715 a 1279 3715 +a +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin { 60.31967 34.1432 } PutCoor PutBegin end + 1279 3715 a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@j0 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 +3715 a 1279 3715 a +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin { 57.47466 36.98865 } PutCoor PutBegin end + 1279 3715 +a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@k0 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 3715 a 1279 3715 a +tx@Dict begin PutEnd end + 1279 3715 a 1279 +3715 a +tx@Dict begin { 60.31967 39.83366 } PutCoor PutBegin end + 1279 3715 a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@l0 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 3715 a 1279 3715 +a +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin { 99.5846 39.83366 } PutCoor PutBegin end + 1279 3715 a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@m0 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 +3715 a 1279 3715 a +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin { 227.62195 0.0 } PutCoor PutBegin end + 1279 3715 +a @beginspecial @setspecial + tx@Dict begin STP newpath /ArrowA { moveto } def /ArrowB { } def + 0.8 SLW 0 setgray 0.25 true 0.0 0.0 56.90549 142.26372 .5 Frame + gsave 0.8 SLW 0 setgray 1. .setopacityalpha 0 setlinejoin 0 +setlinecap stroke grestore end + +@endspecial 1279 3715 a +tx@Dict begin PutEnd end + +1279 3715 a 1279 3715 a +tx@Dict begin { 256.07469 128.03734 } PutCoor PutBegin end + 1279 3715 a 961 3827 a Fa(e)-5 +b(xter)t(nes)1071 4001 y(Ger\344t)1279 3715 y +tx@Dict begin PutEnd end + 1279 3715 +a 1279 3715 a +tx@Dict begin { 227.62195 105.27505 } PutCoor PutBegin end + 1279 3715 a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@p1 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 3715 a 1279 +3715 a +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin { 224.20775 93.89413 } PutCoor PutBegin end + 1279 3715 a 1279 3715 +a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@q1 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 3715 a 1279 3715 a +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin { 227.05276 91.04869 } PutCoor PutBegin end + 1279 +3715 a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@r1 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 3715 a 1279 3715 a +tx@Dict begin PutEnd end + 1279 3715 +a 1279 3715 a +tx@Dict begin { 224.20775 88.20367 } PutCoor PutBegin end + 1279 3715 a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@s1 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 3715 a 1279 +3715 a +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin { 184.94283 88.20367 } PutCoor PutBegin end + 1279 3715 a 1279 3715 +a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@t1 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 3715 a 1279 3715 a +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin { 227.62195 28.45274 } PutCoor PutBegin end + 1279 +3715 a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@i1 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 3715 a 1279 3715 a +tx@Dict begin PutEnd end + 1279 3715 +a 1279 3715 a +tx@Dict begin { 227.62195 34.1432 } PutCoor PutBegin end + 1279 3715 a 1279 3715 a +tx@Dict begin tx@NodeDict begin {0.0 0.0 } false /N@j1 10 {InitPnode +} /NodeScale {} def NewNode end end + 1279 3715 a 1279 +3715 a +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin gsave STV newpath /ArrowA { moveto } def /ArrowB { BeginArrow +1. 1. scale false 0.4 1.4 1.5 2. 1. .setopacityalpha Arrow EndArrow + } def 0.8 SLW 0 setgray /ArrowA { moveto } def /ArrowB { BeginArrow +1. 1. scale false 0.4 1.4 1.5 2. 1. .setopacityalpha Arrow EndArrow + } def /NCLW CLW def tx@NodeDict begin 0.0 0.0 neg 0.0 0.0 0 0 /N@p0 +/N@p1 InitNC { NCLine } if end gsave 0.8 SLW 0 setgray 1. .setopacityalpha + 0 setlinejoin 0 setlinecap stroke grestore grestore end + 1279 3715 a 1279 3715 +a +tx@Dict begin gsave STV newpath /ArrowA { moveto } def /ArrowB { } +def 0.8 SLW 0 setgray /ArrowA { moveto } def /ArrowB { } def /NCLW +CLW def tx@NodeDict begin 0.0 0.0 neg 0.0 0.0 0 0 /N@q0 /N@q1 InitNC +{ NCLine } if end gsave 0.8 SLW 0 setgray 1. .setopacityalpha + 0 setlinejoin 0 setlinecap stroke grestore grestore end + 1279 3715 a 1279 3715 a +tx@Dict begin gsave STV newpath /ArrowA { moveto } def /ArrowB { } +def 0.8 SLW 0 setgray /ArrowA { moveto } def /ArrowB { } def /NCLW +CLW def tx@NodeDict begin 0.0 0.0 neg 0.0 0.0 0 0 /N@q1 /N@r1 InitNC +{ /AngleA 0. def /AngleB 90. def 0.67 0.67 NCCurve } if end gsave +0.8 SLW 0 setgray 1. .setopacityalpha 0 setlinejoin 0 setlinecap +stroke grestore grestore end + 1279 3715 a 1279 3715 a +tx@Dict begin gsave STV newpath /ArrowA { moveto } def /ArrowB { } +def 0.8 SLW 0 setgray /ArrowA { moveto } def /ArrowB { } def /NCLW +CLW def tx@NodeDict begin 0.0 0.0 neg 0.0 0.0 0 0 /N@r1 /N@s1 InitNC +{ /AngleA -90. def /AngleB 0. def 0.67 0.67 NCCurve } if end +gsave 0.8 SLW 0 setgray 1. .setopacityalpha 0 setlinejoin 0 setlinecap +stroke grestore grestore end + 1279 +3715 a 1279 3715 a +tx@Dict begin gsave STV newpath /ArrowA { moveto } def /ArrowB { BeginArrow +1. 1. scale false 0.4 1.4 1.5 2. 1. .setopacityalpha Arrow EndArrow + } def 0.8 SLW 0 setgray /ArrowA { moveto } def /ArrowB { BeginArrow +1. 1. scale false 0.4 1.4 1.5 2. 1. .setopacityalpha Arrow EndArrow + } def /NCLW CLW def tx@NodeDict begin 0.0 0.0 neg 0.0 0.0 0 0 /N@s1 +/N@t1 InitNC { NCLine } if end gsave 0.8 SLW 0 setgray 1. .setopacityalpha + 0 setlinejoin 0 setlinecap stroke grestore grestore end + 1279 3715 a 1279 3715 a +tx@Dict begin { 62.59595 108.1205 } PutCoor PutBegin end + 1279 3715 +a -35 x Fa(Proz)n(essor)47 b(schreibt)g(in)f(Output-P)-8 +b(or)7 b(t)1279 3715 y +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin { 62.59595 88.20367 } PutCoor PutBegin end + 1279 3715 +a 118 x Fa(Proz)n(essor)47 b(liest)f(Input-P)-8 b(or)7 +b(t)1279 3715 y +tx@Dict begin PutEnd end + 1279 3715 a 1279 3715 a +tx@Dict begin gsave STV newpath /ArrowA { moveto } def /ArrowB { BeginArrow +1. 1. scale false 0.4 1.4 1.5 2. 1. .setopacityalpha Arrow EndArrow + } def 0.8 SLW 0 setgray /ArrowA { moveto } def /ArrowB { BeginArrow +1. 1. scale false 0.4 1.4 1.5 2. 1. .setopacityalpha Arrow EndArrow + } def /NCLW CLW def tx@NodeDict begin 0.0 0.0 neg 0.0 0.0 0 0 /N@i1 +/N@i0 InitNC { NCLine } if end gsave 0.8 SLW 0 setgray 1. .setopacityalpha + 0 setlinejoin 0 setlinecap stroke grestore grestore end + 1279 3715 a 1279 +3715 a +tx@Dict begin { 221.93147 31.29819 } PutCoor PutBegin end + 1279 3715 a -1051 3680 a Fa(e)-5 b(xter)t(nes)48 +b(Ger\344t)f(r)r(uft)h(Interr)r(upt)h(auf)1279 3715 y +tx@Dict begin PutEnd end + +1279 3715 a 0 TeXcolorgray 0 TeXcolorgray eop end +%%Trailer + +userdict /end-hook known{end-hook}if +%%EOF diff --git a/common/io-ports-and-interrupts.pdf b/common/io-ports-and-interrupts.pdf new file mode 100644 index 0000000000000000000000000000000000000000..68f6bbb914577f9039f0db419da2ada3fac741c0 Binary files /dev/null and b/common/io-ports-and-interrupts.pdf differ diff --git a/common/io-ports-and-interrupts.tex b/common/io-ports-and-interrupts.tex new file mode 100644 index 0000000000000000000000000000000000000000..149f95b902fbe97e8f38d8692b7807106f376c35 --- /dev/null +++ b/common/io-ports-and-interrupts.tex @@ -0,0 +1,43 @@ +\documentclass{article} + +\usepackage[utf8]{inputenc} +\usepackage[german]{babel} +\usepackage[T1]{fontenc} +\usepackage{helvet} +\renewcommand*\familydefault{\sfdefault} +\usepackage{pstricks,pst-node} + +\pagestyle{empty} + +\begin{document} + \psset{unit=1cm}% + \begin{pspicture}(0,0)(10,6) + \rput(0,0){\psframe[framearc=0.25](2,5)} + \rput(1,4.5){\makebox(0,0)[t]{Prozessor}} + \rput(2.0,3.7){\pnode{p0}} + \rput(2.0,3.3){\pnode{q0}} + \rput(2.0,1.0){\pnode{i0}} + \rput(2.12,1.2){\pnode{j0}} + \rput(2.02,1.3){\pnode{k0}} + \rput(2.12,1.4){\pnode{l0}} + \rput(3.5,1.4){\pnode{m0}} + \rput(8,0){\psframe[framearc=0.25](2,5)} + \rput(9,4.5){\makebox(0,0)[t]{\shortstack{externes\\Gerät}}} + \rput(8.0,3.7){\pnode{p1}} + \rput(7.88,3.3){\pnode{q1}} + \rput(7.98,3.2){\pnode{r1}} + \rput(7.88,3.1){\pnode{s1}} + \rput(6.5,3.1){\pnode{t1}} + \rput(8.0,1.0){\pnode{i1}} + \rput(8.0,1.2){\pnode{j1}} + \ncline{->}{p0}{p1} + \ncline{q0}{q1} + \nccurve[angleB=90]{q1}{r1} + \nccurve[angleA=-90]{r1}{s1} + \ncline{->}{s1}{t1} + \rput(2.2,3.8){\makebox(0,0)[lb]{Prozessor schreibt in Output-Port}} + \rput(2.2,3.1){\makebox(0,0)[lt]{Prozessor liest Input-Port}} + \ncline{->}{i1}{i0} + \rput(7.8,1.1){\makebox(0,0)[rb]{externes Gerät ruft Interrupt auf}} + \end{pspicture} +\end{document}