diff --git a/.gitignore b/.gitignore index 894a44c..72bc282 100644 --- a/.gitignore +++ b/.gitignore @@ -1,104 +1,15 @@ -# Byte-compiled / optimized / DLL files __pycache__/ -*.py[cod] -*$py.class -# C extensions -*.so +x86_assembly/build/*.bin +x86_assembly/build/master.img +x86_assembly/build/master.vmdk +x86_assembly/build/bx_enh_dbg.ini +x86_assembly/build/master.img.lock -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST +x86_assembly/bochs/pkg +x86_assembly/bochs/src +x86_assembly/bochs/bochs-2.6.11* -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ +*.o +*.out +*.bin diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..bcca3af --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,50 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "gcc - Build and debug active file", + "type": "cppdbg", + "request": "launch", + "program": "${fileDirname}/${fileBasenameNoExtension}.out", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "C/C++: gcc build active file", + "miDebuggerPath": "/usr/bin/gdb" + }, + { + "name": "make - Build and debug active file", + "type": "cppdbg", + "request": "launch", + "program": "${fileDirname}/${fileBasenameNoExtension}.out", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "make: make build active file", + "miDebuggerPath": "/usr/bin/gdb" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..6d1f3d5 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,47 @@ +{ + "tasks": [ + { + "type": "shell", + "label": "C/C++: gcc build active file", + "command": "/usr/bin/gcc", + "args": [ + "-m32", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}.out" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + }, + { + "type": "shell", + "label": "make: make build active file", + "command": "/usr/bin/make", + "args": [ + "${fileBasenameNoExtension}.out" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/README.md b/README.md index 0a015fb..b7b2adb 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,37 @@ # computer - 计算机体系结构 -## 组成原理 - 一个8位二进制CPU的设计和实现 +[本项目地址](https://github.com/StevenBaby/computer) + +## 一个8位二进制CPU的设计和实现 ![snapshot](./cpu/snapshot.jpg) -- [视频教程相关 bilibili 频道](https://space.bilibili.com/491131440/channel/detail?cid=163546) +- [相关 bilibili 视频](https://www.bilibili.com/video/BV1aP4y1s7Vf) + +- [LogicCircuit](http://www.logiccircuit.org/) + + +## x86 汇编语言 + +> 不同视频的代码请查看 git commit 历史。 + +- [相关 bilibili 视频](https://www.bilibili.com/video/BV1b44y1k7mT) + +- [Ubuntu 配置 bochs 的方法](./x86_assembly/docs/Ubuntu%20配置%20bochs%20的方法.md) 感谢 [@烟花笑寂寞](https://github.com/1126zk) + +- [参考资料](./x86_assembly/docs/参考资料.md) + +## 操作系统实现 + +![](./snapshots/onix.jpg) + +- + +- [相关 bilibili 视频](https://www.bilibili.com/video/BV1gR4y1u7or/) + +## Linux 源码分析 + +- -- [LogicCircuit](http://www.logiccircuit.org/) \ No newline at end of file +Working on it, coming soon..... diff --git a/computer.code-workspace b/computer.code-workspace index 3c7c0c1..bfe91ff 100644 --- a/computer.code-workspace +++ b/computer.code-workspace @@ -16,13 +16,13 @@ }, "launch": { "version": "0.2.0", - "configurations": [{ - "name": "Python: Current File", - "type": "python", - "request": "launch", - "program": "${file}", - "console": "integratedTerminal", - "justMyCode": false - }] + // "configurations": [{ + // "name": "Python: Current File", + // "type": "python", + // "request": "launch", + // "program": "${file}", + // "console": "integratedTerminal", + // "justMyCode": false + // }] } } \ No newline at end of file diff --git a/cpu/snapshot.jpg b/cpu/snapshot.jpg index ffc6e99..f569c76 100644 Binary files a/cpu/snapshot.jpg and b/cpu/snapshot.jpg differ diff --git a/logic/vga/VGA.CircuitProject b/logic/vga/VGA.CircuitProject new file mode 100644 index 0000000..463ae96 --- /dev/null +++ b/logic/vga/VGA.CircuitProject @@ -0,0 +1,3879 @@ + + + + 8a9458c3-1049-4be3-8c5c-43f32e1dd8e7 + 2.0123595505618 + 50 + True + 113983b6-1055-4f58-8d8e-031737abac1b + + + 1fae8778-f915-4e77-8bcc-8cae92219887 + Main + + + fa3a03ab-3c04-485f-a3c9-042111811c4a + PC8 + PC8 + CU + + + c3fc1c75-abc0-4507-886e-c4b544c5929d + T> + T> + Flip-Flop + + + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + D> + D> + Flip-Flop + + + 299acfd6-b7e2-4e08-b753-c450be050266 + D + D + Flip-Flop + + + 4be7afd3-d19c-4818-9855-f7d539d7a999 + R-S + R-S + Flip-Flop + + + 113983b6-1055-4f58-8d8e-031737abac1b + BingBinb + BB + + + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + PC14 + PC14 + + + 892dc501-d343-42b6-8ba7-2a542a9be9ec + fa3a03ab-3c04-485f-a3c9-042111811c4a + Clear + CLR + + + 738110f5-1912-4f41-8d63-a6ce2abdbd00 + c3fc1c75-abc0-4507-886e-c4b544c5929d + Top + Clear + CLR + + + 0bf744c5-3a28-4274-8f04-082c39868cee + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + Output + Right + Q' + Q' + 1 + + + 256097f0-32fd-42cf-8279-99c3c3055d84 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + CP> + CP> + 1 + + + 49661708-f0c9-486f-bc4a-2ff690d6a756 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + D + D + + + 21d246dd-26dc-4900-9f92-04ace4922818 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + Output + Right + Q' + Q' + + + e7c1984e-84c5-452d-9657-ebcd42d506e5 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + Reset + R + + + c9daa10a-afb2-4b15-a109-8d2e2879d1c4 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + Bottom + Pre + PR + + + 19e9f909-ba68-461c-8494-84227741d922 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + Top + Clear + CLR + + + d64c5104-a47c-4369-a6bb-157f04847b93 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + Output + Right + Q + Q + + + 81062a2c-342c-43df-8f2b-ab126928c237 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + Set + S + + + 160dd8e7-c3a2-4448-bf04-9f0232d5529b + 299acfd6-b7e2-4e08-b753-c450be050266 + Top + Clear + CLR + + + a8a7ab03-ee21-4162-a97b-10a75b15a158 + 299acfd6-b7e2-4e08-b753-c450be050266 + D + D + + + 14539b85-250b-467d-8ffc-26a9ad2967c8 + 299acfd6-b7e2-4e08-b753-c450be050266 + Output + Right + Q + Q + + + d00662d2-fbca-4b37-bce3-c1ea79c9f23b + 299acfd6-b7e2-4e08-b753-c450be050266 + Output + Right + Q' + Q' + 1 + + + e688d880-c0f0-42de-9e2f-efa5620879d4 + 299acfd6-b7e2-4e08-b753-c450be050266 + EN + EN + 1 + + + a285b49d-e590-4a03-932b-6c8e2c62b56d + 299acfd6-b7e2-4e08-b753-c450be050266 + Bottom + Pre + PR + + + efa8c263-48a7-4605-9dcc-8c6c3c4cfa4a + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + Top + Clear + CLR + + + d5999d18-6060-45a9-816c-648fabeb55e6 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + Output + Right + Q + Q + + + 33f62b27-36d1-4808-8c88-b5c2aae1b581 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + Bottom + Pre + PR + + + 905d858b-cfd9-46a2-a057-c519d6c9e559 + c3fc1c75-abc0-4507-886e-c4b544c5929d + Output + Right + Q' + Q' + 1 + + + dea1e7b0-e1e2-4e55-aaf6-6e24628ff31b + c3fc1c75-abc0-4507-886e-c4b544c5929d + CP> + CP> + + + 9ef8502e-6d79-48a7-a745-4b00331e527d + c3fc1c75-abc0-4507-886e-c4b544c5929d + Output + Right + Q + Q + + + 3e51679f-92f6-4ab8-87d0-6b18500867d5 + c3fc1c75-abc0-4507-886e-c4b544c5929d + Bottom + Pre + PR + + + eb4b7af6-14a3-4724-9044-1dfc42ef2705 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 8 + Output + Bottom + O + O + + + 52d2a7ae-cd5c-4a5e-a92d-eb2dd249c9bc + fa3a03ab-3c04-485f-a3c9-042111811c4a + Pre + PR + 1 + + + f00cc385-0b10-46c5-ac47-ae9d2b3464d7 + fa3a03ab-3c04-485f-a3c9-042111811c4a + CP> + CP> + 2 + + + d53476dc-fcbb-42fe-9c2b-781ba4cbb0b3 + fa3a03ab-3c04-485f-a3c9-042111811c4a + Right + EN + EN + + + 1a8a57a2-1742-4bbb-a317-29f455b17c9d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + Clear + CLR + + + 2f388674-0d48-4b4d-b22c-61dfc0899fac + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 14 + Output + Bottom + O + O + + + c82fd9ca-6ac4-450d-9601-9ca1803ead11 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + Right + EN + EN + + + df51f392-2baf-442f-a069-6a7f420b7d9a + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + Pre + PR + 1 + + + a218fe54-6032-4545-9244-77de0c5877bd + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + CP> + CP> + 2 + + + 6228e567-640a-407b-a076-c816361f75d4 + 6228e567-640a-407b-a076-c816361f75d4 + + + 1a2ed47e-66e2-43d9-9665-f16f88ba6b0c + 1a2ed47e-66e2-43d9-9665-f16f88ba6b0c + + + f72959d5-18ba-4efc-b1e4-fcca76df2c5c + + + bfa87be6-d5b7-4270-92a0-00a02083c2d9 + + + ba46bbb3-5c3f-45ee-9435-7b57a098ab10 + True + + + 9e2f1732-790b-482c-9d8e-594f34765d20 + True + + + 9a2838ce-2c7f-4c0d-a4e0-f65b4ac875bc + 14 + 8 + ///////////////////////////////////////////////////////////////////////f/9// +3//f39/f/9/f/9/f///f//////////////////////////////////////////////////////// +/////////////////////////////////////////////9///9//3//f/9//39/f39/f3//f/9// +/9//3////9//////////3////9////////////////////////////////////////////////// +///////////////////f///f////3////9//39//3///3//f39/f39/f39//3//f3///3//f/9// +3///3///3//f///////////////////////////////////////////////////////////////f +///////f///f/9//39/f/9//39/f/9/f39/f39/f39//3//////f///////f/9//3//f3/////// +/////////////////////////////////////////////////9//3//////////////f///f39/f +/9/f3//f39/f39/f39/f39/f3//f/9/////f/9//////3//f///f3/////////////////////// +////////////////////////////3///////3///3///3////9///9//v9/f/9/f3//f/9/f39/f +39//3//f////39/f3//f3//f///f/9/f///f//////////////////////////////////////// +///////////f///////f///f///f/9///9/f39+/39/f/9/f39/f39/f3//f39/f/9/f3///3//f +3//f/9/f/9///9/f/////////////////////////////////////////////////////////9// +///////f/////9/f39/f39/f/9/f39/f39/f39/f3//f39/f3//f/9//3///3//f/9//39/////f +3//////////////////////////////////////////////f/////////9/////////f39/f/7/f +37/f39/f39/f39/f39/f39/f3///39//39//39//3//////f/9//39/f///f//////////////// +///////////////////////////f/9/////f/9///9//3//f/9/f39/f37/f39/f39/f39+/39/f +39//3//f39/f3///3//f39/f39//////3///39/f//////////////////////////////////// +////////3////9/////////////f/9/f39/fv9+/vr+//9/fv9/f37/f39/f39/f3//f/9/f3/// +////3//f39/f/9//3//f3///////////////////////////////////////////3//f///f//// +3//f3//f/9/f39/fv9+/uru+39+/37/f37++39/f39/f3//f39/f/9/f39//3//f39/f39//3//f +3//////////////////////////////////////////f3//f///f////3///////39/f37/fv76/ +urqaur/f376/vt+/u9/fv9/f3//f39//3//f/9//3///39//3//f39/f3//f3/////////////// +/////////////////////9/////f////3//f/9//39/f/9/fv9/fvr+7uo6aupq637+6u7q7vr/f +377f39/f39/f39//39//3//f3//f/9/f/9//39/f3/////////////////////////////////// +////3//f/9/f///f///f/9/f/9/f39+/v7+7urqOjo66v76umrqauru637+/39/f39/f39/f/9// +39/f///f39//39/f39//3//f////////////////////////////////////3///3//f///f3//f +/9/f39/f37++v7q6urqaro6OurqOjo6Ojpq7vru6vr/f39/f39+//9/f/9/////f////3//f/9/f +3//f////////////////////////////////////3///3//f3//f3//f/9+/39/f37++v7u6uruO +jq6Ojrq6ro6OjnGauruaupq737/f39/f39//39//39/f/9/f3//f/9//3//f3/////////////// +////////////////////3///3//f3//f39/f39//39/fv9+6u7q7vrq6ro6uro6Ouq6ukXFBjpqO +upqOut++377f39/f39/f3//f///f/9/f39/f39/f3//f///////////////////////////f//// +3//f/9//39/f/9/f/9/f37/fv76/mrq/urq6uq6uuq6Rjq6uuq5yQXGOjo6Oar6/u7+7v9++v//f +/9//37/f/9/f///f39/f/9+////////////////////////////f///////f/9//39/f/9/f37/f +v9++v7q6u7q6uq66rrq6urqujpGuurq6ro5RcW6ObnGaurq+ur6/39/f39/f3//f3//f3//f39/f +37/f/9///////////////////////9//////39/f///f/9/f/9/f376/376/uru6mrqau766rrq6 +rq6uvq5xjrq6rq6RQVFxao5uco6aupqau77f39/f3//f3//f3//f///f39//39/f//////////// +/////////9//39///////9/f3/+/39/fv767vru6mo6amo66urq7urq6rq6+rq66kXGukXFRbkFB +IXFujnFqjo6Ojru7v9/f39//39/f39/f39/f///f39//3////////////////////9///////9// +39//3//fvt/f37+aurqOjq5ujpqOjrq6urrOvq6uzr66uq5ljo5qcXFRRSFBYW5uUY5ucY6/ur7f +vt/f3//f/9/f39//39///9/f3////////////////////9///9//39///9///9/fv5rf37qajo6O +bo6OUXGujo6Ojq6uvrrOur66zq6ucXGurq6Ojo6OcVFxQUFyUWpumo6737/f3//f39/f39//39/f +39/f39//////////////////3////9///9//3//f/7/f35q635qOmnFRjnGOUUGOmo6urq6Ors66 +vrraur6uuo6Ourquus6uro5xQSFFRUFFRY6Our663//f39//39/f3//f39//39/f//////////// +////3//f/////9//3//f/9/f376OmrqOmo4hIY5BjnJxjq6uurqurr66zrq63tq6uq6uka6+zq6u +zq6ucUEAQSEAIUFujru7v9/f39/f39/f39/f39/f3///v//////////////////////f3//f3//f +///fut+ObrqOjnJRQUFRUVFxcXGurq6+zr7Orr7autq+2r6urpGuzr7Ovr7Oro5lIQAhAAAAUY6a +jr7f377f39/f3//f///f39/f3//f/////////////9///9/f///f3//f3//fv5q6QY6OjlFFQQAh +QUFBka6Orr6urrq6rr7autq+2tquzq6urq6urs6urs6ukUEAAAAAIXFyUXG/39+7v9/f3//f39/f +39/f39//3////////////////9/////f39/f3//f/5qObgBRUVFRQQAAAEFRcZKRrpGurs6uzr7O +vtre2tu+ur6urq6ukZFxRWVFka5xIQAAAEFBUSFRu9++ur/f3//f/9/////f39/f39////////// +////3///39///9//37//35pxcUEhUUFBQUEAAEFhcZFhRUFRQXGOzq7Outre2r7autquvq6tjo5R +ASEAIQBBcUEAISFBUUEhQb/fu7q639/f39/f39/f/9/f39/f///////////f///f3///39/f39/f +/79RAUFBAEEhIUEhAEFxYUEhQSEhISEARZW6vtre297bvtq+us6uQY6bQSEhQVEhAEFhIUEAIUFB +IVG6vrqOmt/f/9//3//f/9/f39/f3////////////9//3//f3//f39++37puIQAAAAAhAAAAACFl +YSEARZqOISEAQUFx2s662t7b3tq+zrq6kXGurm5hUXFxYUFBZQAAIQAhJSFRlpq6bo6/39/f39/f +/9/f/9/f39/////////f/9//3//f///fv9/fv79uAAAAAAAAACEAACFBQQBBQWGOcUFlcYqRrq6+ +2t7a3t/a2rq6urq6rq7Orq6qrpGRYUVBAAAhAABBanGajm6uvv/f39/f39/f/9/f3//f//////// +/9//39/f3//f377fvttxIQAAAAAAACEAIQAAQWFlhZGuka6urq6urq7a2tre2vve3rrautq6zq7O +rs6urq6urpFxQUEAACEAQSFqbnFqjrvf39/f/9//39/f/7/f3//////f///f/9/f/9//37+6345u +QQAAAAAAAAAAAAAAQUVlka6uzs7Ozs7Ozrravtre+t7f3t/aur662r7avt7e2r7Ozq6ujnFBIQAh +QUVFRUFRcW6+v77f39/f39/f39//39////////+/3/++/9/f3766uppRQQAAAAAAAAAhIQAhAEFx +ka6uzq7Ovs6+urre3tre2t7f/t/6vrra2r7a2tra2tra3rq+zq6RQQAAIUEhQQAhQVFuupq639+/ +/9/f/9/f39/f//////+/3v+/39/f3767jo5RQSEAAAAAAAAAIQAAAABhjq7Ozr7e2tra2t7e2tve ++977+v/73tu62r7a2t7e297a3tra2s6urnFBACEAAAAhQVFBco6Ou9++39/f39+/39/f3////9// +39/fvt/e/767cVFxIQAAAAAAAAAAIQAAIQBBca7Ovtra2t7a3tra39773vve+/77/97aurravt/b +3t/e297a3tq+zq6RQQAAIQBBRVEhIVGOjt+6ur7f/9/fvt/f/9//////v97f37q+39+ubkFBIQAA +AAAAAAAAAEEAAAAAQa7Oztra3tre297f3vrf3v/6/977/vr72tq+u9ra3t/e39772tra2r7OrmUA +AEEhIUEhAEFxupq6bprf39/fvt/f39/f3//f377f3766uv+7cQAAAAAAAAAAAAAAACEhAAAAAIWu +rt7a3vr639773vvf+v/e+/77/vv/+97autrbvt/63/rb3tre2trOzq5xQQAhAAAAACFRjo6OjnG6 +urq+39/fvr//3//f/77f3766rrrfjmFBAAAAAAAAAAAAAABBAAAhAACRzt7a3vrb3vv73v/f3v/e ++/77+///+v/b2rq63tve397f3t/6297aur6ukUEAIQAAACFBbo5FUVFSv5pu39++u9/f39/f/9++ +39/furq+roVgQAAAAAAAAAAAAAAhQQAAAABBkc7a3tre+/ve//ve+/ve//r73v7///773t/aurre +29/63/re397a2trOrq5lAAAhAABBRUFBIUEhjrpxcbq+urrf39///9++39++urq6mnFhgEEAAAAA +AAAAAAAAACEAAAAARa662tre+977/97////e//re+v///vr73/rb3tq6297e397f297b3tq6vq6u +YQAAIQAhAAAhACFFQXFSUY6uuq66377f39++ut+6ur67uo6BgYFgAAAAAAAAAAAAIUEAACEAAGWR +rt7e+vr6//77//re+/ve+/v+2tr7+t7aurra2r7f29/e+97f2travs7OrnEhAEEAAAAhAAAAQUUh +RWGujq6Rrr7f39/f37q6urq7urqOgWFgYAAAAAAAAAAAACFBAAAAAACBrq7e2vrf/vv7/97//97e ++/7+cQBh2t7argBB3tu62t7e397f2t7autq6rr6RIQBBACEAAAAAACEABWGRsa6uoa66v9//39+6 +mrqauq6Ouo6BYUAAAAAAAAAAAABBQQAAAAAhca7a2t7e+v/++/7/+vv6+9772oFlztrarq5lcdq6 +2trf297f3tve2r66us6ukQAAQSEAIQAhAAAAAEGBkYaxsYGRrrrf397furq6rpqujnFxYWEAAAAA +AAAAAABBQQAAIQAAQZGuzt7a+/77+v/73v/e3vv73tr///ve2tra29u6ur7b3t7f+t/e29ra2rq+ +rnEAAEEhAAAhAAAAAABAgZKxkYGBgY6+/9/f37q6uo6OrpZhYWFhAAAAAAAAAAAAQUVBAAAAAEGR +rr7a+t76//77/v/62vr//vv//v/e+vre3tq+2tra39rf3tve39reur66rq5hIQAhAABBIQAAAAAA +AIGxoYGBgYGRut/f/9+/uppxca6aYWFhQEAAAAAAAAAAIUFBAAAAAAAAka7O3t763/77/vve+t7f +/v///v/6//rf+9/a39rf3rre39re297autq6zq6uRQAAIUEAIQAAIQAAAABhoYGFgYCBkrrfvv/f +37u6ZmFhjpFhYUBAQAAAAAAAAEFFAAAAAAAAIXGuvtra3vr6/977+976+v/+///////e+/7f3t/e +u9/f2t7f3tve277aurqukSEAIQBBAABBAAAhAAAhYWChoaGAoZG6urvf/77fu7puYWGBgWFhQUAg +AAAAAABBQSEAAAAAAABxrs7a3vr/3vr/3vre3977///+//77+t/62tva397avt/b3tve277aur6u +rnEAAAAAQSEAQSEAAAAAAEFhgIChgIGOjrq6///f3//furphQWCBYGBgYUAAAABBRUEAAAAAAAAA +Za7O3t763vr/+t772t76//7///ra7trOzq7Outrfvtva3tve277a2rq6rq5hAAAhAEEAAEEAIQAA +AABBYGCBoYGBgZGuuv/f///f39/fmmFgYIFgYWBgQAAAQUFBAAAAAAAAAEGRvtra3vr++v773t76 +//7/+s7u8dHR0bGxsrGuutu+ut/e277a2rq6zq6RRQAAACEAACEAQQAAIQAAQUCBgIGAgYGRjq7/ +///f/9/f345hYYGAgWBgYUAAAEElQSEAAAAAAAAAkc7a3vre+9773vve3///3tGxoYGhsbGhsbHK +sa66277avtvavtu+uq6ucQAAACEAQQAAQSEAIQAhAABBYIGAgYCBcY7a/////9//37+6YYFggYBh +YGAAACFBQUEAAAAAAAAAIXGu2tre//76/v/62t7Osc6xgbG6uq6urpaRYbGuur662t/a3tq6zrqu +rkEAAAAAIQBBAABBIQAAAAAAQGGAYGBggZGuuv///9//39/fu3FhYGCBYGBhQCEAQQAhAAAAAAAA +AABlrt7ezs7O///ezvHOwKDOroCu///akd6OQQBAgc66277a3rvaur6urpEAAAAAIQAAQSEAAEEA +IQAhAEFhYIGBgaGKrrr/////39/f37+WtqqBYIFgQEEAQUFBAAAAAAAAAAAAAJGxwaHazrHOpbHa +zsHFsbGxkZGu2q7KkUFBAACR2r7b3tveurq6rq5xAAAAIQAAQQAAAEFBACEAAAAAQIGAgKGBka66 +///////f/9/fmo67kWBhYEAAAEFBACEAAAAgga6uroGR0e7//87BspGBrq7B0dHKrqFggbGukaqO +YUEAQdreut++2rrarq6RQQAAAAAAIQBBAAAhQQAAIQBBAEFggYCBgY663//////f///fv7q6imGB +YGFAIQAhAAEAAACh5enO0fGxsbGx2t6u/86uroWB0dLGzrGBgYGBgYGxrmFBAGXa297a2tq+uq6u +cQAAAAAAAAAAAEEAAEFBACEAAEEAQEBhgGCOut/////f///fv9+7mnFhYWBgAABBYWFgYQCl9vbR +wcHGsaGBgYHa2t6usq6uYYGxzrqmkqpgYYGAro5hACCu376/2r66uq6urkEAAAAAAAAAQQBBAABB +QQAAACEAIEFhYYBhjrrf///////f39++37uOZmVhQACB9s7R0cHBztra9sqxobLfroFgkbq6/rGR +roVAgbHakZGukYGBka6BQUGh2tra2r7aurqurnEAAAAAAAAAAAAAQQAhAEEhACEAIQBhQGBgYbrf +3//////f/9+/v7+6rrHOkWGx++7R0tHBrpGFsbHOpqHarqqRYYG6rrqmga6RQWGAgYGBhXGBjpHa +jgChzrq+utq6urqurq1BACFBIQAAAABBAABBACFFQQAAAAAAQUCBYXG639///////9/f39/e7u7u +zrGu/96qsc7K0aGRsYGhsc62rpGqu65BhYGRkZGucUGBgYGFgZFhkd+BjnGBzs6627q+2r7Orq6O +AEFFQVFBAAAAQQAAQUEAQUEhQQAhAEFAYGFyrt/f////3//f3///+s7O8c6Wka6RkbqysYWBkbuu +gYGR26Glrt+7QIGlpoGuYUCRrq6RgYGRjpGuZWGh0a6u2r662rq6rq6uQQBBUXFuYQAAAAAAQUEA +AABBAAAhAAAAQGFhca6/3////9ra3r7O2v/6zs6uuo5xkaqusbGmkaGqrrFhgd+uoYGRrmGBkYGF +kZGFgZGxgbGRYYFggYGhsbKuur7aurq6uq6+cQBBUXKOjnEhAABBAEEgQQBBQSFBAABBAABBYXKu +v97/39razs7aoaHO386xsq6RgbaukZGBrruhpa66hYG6/66BjpGBoYGRroFghYWxurGRgYCBobGx +yrKxrtraut66uq7OkQAAQXGOjrqOAAAAAEEAQUFBAEVBAEEAIUEAAEFxjrvf//b23q6RzrqxgZGu +sbKRhoGujnFhrrGloaGxrnJxuq6BrpFggZGFrt6usc7a+vr6zrGhobGhprGxurq6vtq6us6+rkEA +QXGOurq6jkEAAEEAQQBBAEFFQSEhAAAAQQAAQXG63/v//86yrrL/u6GBhpGuqrKRka5hYZGhoaWq +kZFhka5grrq6gYWu266u+v76/t7e3s7erqqRqrGuurq62tq6urq+zkUAQVGOurq6u7pBAAAAQQBB +RUEhQUEAQQAhAABBQSFBjt/u+v/O7trR2rqqsWFhga6ugZKRcWGBkYG2jpGRgZFgga6O3/+63v/f +ra7e3tr6+trO3tqurq6uurq62r662rraznEAAEGOrrq7vt+6cQBBAEEAAEFFQQBFIUEAAEEAAEFF +QXGazvr6zvHKsbGhrq6RQGCxkYGRioGBgbaxkbHOzrGBpY4ARd///9/e/9+xrt7e3t7e3tre3tra +utq62t/avrravnEAAEFxlrrf39++unFBAABBAABBRUFBRQBBIQBBQUFBQVFmrv//zsGhxaGlgYGR +gWGScYGOrnGBkYGxgWFBZWVlQEEAAEG+////397fupGx2vra+tre2tre2t7a3tu+2rraupEAACFx +lr6/3t/f37txQUEAQUEAQUFFQUEhAEEhAABBRWpxjrv/3rHBpaGhsYGBsXFxhYGBkZGxkZGlgGAA +AAAAAAAAQQAAjv//////3/+6ka7O2t7e+tre2trbvtu+2rq62pEAAABBjrvf39/f3/+7cUFBAABB +AEFFRSFFQQBBAEFBQXGOjrq+3q6xoaWBkaqBsZGBYIFghYFhrrGFhUFBQUEAAAAAAAAAAHH///// +///f39+63t7a2t762tq+2rraurra3nEAAAAAQb7f3////9//vnJRQQBBQUEhRWFBRSEAQSEAAEFu +co6au9ulgIGhkaqukYGhpbGxxaVAIQCBwWEgQEEAQQAAAAAAQQBR3///////39/f/9///9q62r66 +urq6utq6rnFBQQAAAEGu3//f3//f39+RUUEAQUUAQUFRQUFBIUEAAEFBcY6Ourv/xoCBgaGFrq6F +rq6xkYVFAAAAge7BYUFAQQAAIQAAAAAAQd7/////////397f////ka7Ors6uzq6ukWUgQUAAAEEg +jt/////f3/+7jmVBQQBBQUFFQXFFQQBBQQAAQVGOmpq6/66lpaWlsdHe8a5xQSEAIUEAAGHxcUFA +YQBBAAAAAAAhAAC6///////f/9/f397f/5plka6RrpGRZUVFQUEAAEFlQXH////f///f3o5RQQBB +QUUAQWFRYUEhQQAAAEFhbq6auv/ezrHOzt71za5lQUEAQUEAAAAAoaFucQBBAAAhAAAAAAAAjv// +///f/9//396/3v/fZUFlcWVlRUFFYUVAAEFBUUGO/////9///7+OYUFFQUVBQUVRYUEhAEEAIQAA +QVGOjpr/3////9qxUUFgYWFBQSBBQQAAAABgsZZxQQAAAEEAAEEAAGX/////39///9/f3t///7+O +ZXFxYUVlQWVBQQBBcVGOut/////f3//fjlFBQQBBRUFhcVJBACEhAAAAACFBjpq639///66BAABg +gIFlZUEARUEhAAAAAEFhcnFBAAAAAAAAAAAl/////9//39//3////////9uOilFhQWVFQCBBUXKO +ut///////9//345RQUVBIUElQWFFQXFRIQAAAAAAQUFxjt/asaFgQCBgoaGFYWFBQUFBAAAAAAAA +IGFxQQAhACEAAAAAALr////f39//3////////////9+6bmVlQUEARY6u3////////////9+OYUFB +AEFFQUFRQXH/lgAAAAAAAAAAQVHRwGBAQECAwcGBgWVFAEFFQUEAAAAAAABBYWVBAAAAAEEAAABx +/////9//39/////////f/9///9+OcQAgQXGW3///////3///39/fjlFBRSFFQUFBUUFRjlEAAAAA +AAAhACFBoUBgYIChwcGlgGFxYUEAQUVBAAAAIQAAQUFhZSEAACEAQQAAQf/////f3//f//////// +/9//3///37phQXGOuv///////9//////345FQUFBRUFFQUFRclEhAAAAIQAAYWFBRYCh4cHB5cWh +oYGRZUEAQUVFQSEAAAAAAABFQWFBIQAAQQAAAACa/////9/fvv///////9/////f////325yjr7f +///////f3////9+ORSFFIUElQUFBcXEhAAAAAAAhAEBhZYrR4dHB0cGhoYCBcUEAAEVBQUEAAEEA +AAAAQUEgQQAAQUEAAAAAUf/////e3///////////3//f///f//+6jpra3///////39//3/+7cUFB +QSFFQUFFQVFBACEAAAAAAAAhQGBh0dHBwcGhoaCBkWFBAABBRUVBAAAhQQAAAEFFQQAAIUEAAAAA +AACO////////////////3////9///9///9+6vt//3///39/e///fmnFBRQBBQQBBQWVhIQAAAAAA +AAAAAEFhYebRwcXBxaGBZXFBAAAAQUFBQUEAAAAAAABBQUEAIQBBAAAAAAAAQd////////////// +////////////////39/f////3//fuv//v45RAEEhACFBRUFhYSEhAAAhAAAAAAAAQGHRwcXBoYFg +YXFBAAAAAABFQQAAAEEAIAAAQUUhAABBQQAAAAAAAABx/////////9//3////////9////////// +////3///vq7//9+OQQAAAEEAIUFFYYFBAAAAACEAAAAAAEFAwaGhgWBhYWVBAAAAAAAAQUEAAEEA +AAAgIEFBAEFBQQAAAAAAAAAAAG7////f/9/////////f////////3////9//3///366+//+7cQAA +AEEAQUFFQUFhYQAAAAAAACEAAEEAAIFlYWVhQUVBACEAAAAAQUFFIQAhICAAAEFBAEEAQUEAAAAA +AAAAAAAAuv/f/9///9///9/////f/9//3///3///3//f3766///funEAAAAAIQBBQQBhgWEAAQAh +ACEAQQAAAEGhYWFBIEEAAABAAAAAAABBQQAAAAAgAABBQQBBQUUhACEAAAAAAAAAAEG+//////// +3////9///9//3//f/9/f/9/f/9+63///344hIEAhAAAhAAAAQIFBAAAAAAAAACFBAAAAoYVhQEFA +QUBhQAAAQQBBQQBBQQAAAABBIEFBQQBBQQAAAEEAAAAAAAAAUf//3//f////3///39//3//f/9// +39///9++3////99xIEBhACEAAEEAIWFBAAAAACEAIQAAAEFBQYGBYGFgYWBgQCBBQUBAQUUhAABB +QQBBQUFBAABBQQAhACFAIAAAAAAAAABu////////3///3///3//f/9/f39//39++3/////+7QUBh +QAAAACEAIUFBIQAAIQAAIQAAAAAAAEGhoaGAgWBhQUFAQUBBQUFBAABBQEEAQQAAAEFBRSEAIQAA +QEEAAAAAAAAAAK7/3//f/9//39/f3//f39/f/9//39++39//3///jgBhYGBBIUFBAEEAAEEAIQAh +AAAhIQAAAAAApaGBgWBBQEBgQEFAQUFFQUFBQUFBAABBQQAAQUEAQQAAAEAAAAAAAAAAAAAAvv/f +/9/f3///3//f/9//39/f39++2///////30FAYGGAYQAAQUEAQSFBIQAAACEAACEhAAAhAKGBgIFh +YIFhYGFBQUAgQUVFQUFhQEFBAABBQUVBAAAhAEEAAAAAAAAAAAAAAEG+/9//3//f3//f/9/f3//f +3/+6v//f/9///5ZAYIFggWBBIQBBQUEAAAAhAAAAIQAAQSEAACGBoKGBgIFgYGBhQEFAQUEAQWFA +YUFAQUBBQQBBQQAhAAAAAAAAAAAAAAAAAAAAQb7f3v/f3//f/9/f/9/f39+/vv///9////9hQGBg +gYChYQBBRSFFQSFBACEAAAAAACEAQSEAgIGAgIFggIFhYEFAQQAAQUAAYWBhQGFhQUBBQQAhAAAA +AAAAAAAAAAAAAAAAAABBmt/f3//f/9//39/f/9++3////9////+OQGCBgYGhgUAAQSEAQQBBQUFB +QSEAIQAhAEFBIZGWioGAgYCBYEBBQEBBAABAAGGBgWFgYWFhRUEAQQAAAAAAAAAAAAAAAAAAAAAA +QXGO3v/f/9/f3//f39/f3////9//3/+/QUCBgKGAYGEAAABBAEFBAEEAQQBBQQAAACEAQUG/mpqO +gYCBgUBhQABBAEEAQEFAgICBYYFgQSBBQQAAAEFAgKGhQAAAAAAAAAAAAEFxcY6+39///9/f3//f +3////9//3/+/YUBggaFgYUBgIABBAEEAAEEAQQBBIUEhACEAISFBmm6a34GAYGBhYEBAQQAAAEFA +QIGBgIBgYUBBQQAAAABAgYChwcGBYEAAAAAAACEAQXJxjq6+vr/f/9/f3////9/f39/fikBgoYFg +YWBgYQAAAAAAQUEAQQAAAAAhACEAAEEAQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + + c6c9fb96-de72-4d1b-92f4-a9192c9d67de + 8 + 8 + True + + + cc768a97-db83-4462-8f8c-dcba35ac5c56 + 14 + 14 + True + + + aa935336-2235-4775-9284-3b5f69282b22 + Random + 8 + 16 + 16 + 4 + + + f3a63e93-a141-4848-9a3b-80b04f281ca5 + Random + 8 + 100 + 100 + 2 + + + 06522f4d-5ad0-4105-8f94-2aeaf7d85b9c + 892dc501-d343-42b6-8ba7-2a542a9be9ec + fa3a03ab-3c04-485f-a3c9-042111811c4a + 5 + 14 + + + 83545e73-2dd4-40f2-95fb-c553efdb2845 + 00000000-0000-0000-0000-000000040200 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 8 + 16 + + + 770a0294-92e8-4b51-8c99-1b3ea1f9f22f + 738110f5-1912-4f41-8d63-a6ce2abdbd00 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 15 + 6 + Right + + + 5b921822-6f8e-44cf-acc6-c0d65596c3bd + 0bf744c5-3a28-4274-8f04-082c39868cee + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 31 + 11 + + + 7ff25598-67b7-42ed-8b55-cbb48e84446d + 256097f0-32fd-42cf-8279-99c3c3055d84 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 11 + 11 + + + 7ac693f1-e3be-4ee0-88b9-8c5c835c9511 + 49661708-f0c9-486f-bc4a-2ff690d6a756 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 11 + 9 + + + 9cda9f84-12d8-4a0e-97d7-b0b2ba75f351 + 21d246dd-26dc-4900-9f92-04ace4922818 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 19 + 13 + + + d64a3d18-945f-4bb4-99cc-4b40b4580e0e + e7c1984e-84c5-452d-9657-ebcd42d506e5 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 9 + 8 + + + 6eda7edf-3347-47f5-9ec7-211f28796e25 + c9daa10a-afb2-4b15-a109-8d2e2879d1c4 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 11 + 16 + Left + + + 7a5f5af8-1f4d-4456-aba8-91b8d8370837 + 00000000-0000-0000-0000-000000030301 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 13 + 12 + + + 517fa9c0-9a46-4064-a3fc-2d9b51588f1d + 19e9f909-ba68-461c-8494-84227741d922 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 11 + 5 + Right + + + a2030de3-2f22-4207-80ee-01aeb9c7b3ea + d64c5104-a47c-4369-a6bb-157f04847b93 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 19 + 8 + + + 159c55b2-ee44-4795-b246-05a92af695b7 + 81062a2c-342c-43df-8f2b-ab126928c237 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 9 + 13 + + + 898f197c-1d97-4545-bddc-905c4dae6dc9 + 00000000-0000-0000-0000-000000030301 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 13 + 7 + + + 267d2aa6-827b-4260-a32e-f4452490eea2 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 299acfd6-b7e2-4e08-b753-c450be050266 + 19 + 6 + + + de02282d-384a-4b70-bb02-6cd1bedb52b7 + 160dd8e7-c3a2-4448-bf04-9f0232d5529b + 299acfd6-b7e2-4e08-b753-c450be050266 + 19 + 2 + Right + + + 34aa7945-2e03-419a-a9f3-9fbbc0e3cebc + 00000000-0000-0000-0000-000000020101 + 299acfd6-b7e2-4e08-b753-c450be050266 + 10 + 3 + + + e02ed420-8a04-4acc-be29-715e2254cc23 + a8a7ab03-ee21-4162-a97b-10a75b15a158 + 299acfd6-b7e2-4e08-b753-c450be050266 + 5 + 10 + + + 313cd665-a688-4a8a-bcb7-728ad527fb2e + 00000000-0000-0000-0000-000000040200 + 299acfd6-b7e2-4e08-b753-c450be050266 + 14 + 4 + + + 3c519da8-66d8-4b27-b3b5-d5cf7f516523 + 00000000-0000-0000-0000-000000040200 + 299acfd6-b7e2-4e08-b753-c450be050266 + 14 + 8 + + + e3ab1fdf-3dcb-4073-bd14-30696501ed51 + 14539b85-250b-467d-8ffc-26a9ad2967c8 + 299acfd6-b7e2-4e08-b753-c450be050266 + 24 + 6 + + + d667edf4-f5fb-48ad-a8fb-e58de24d40e8 + d00662d2-fbca-4b37-bce3-c1ea79c9f23b + 299acfd6-b7e2-4e08-b753-c450be050266 + 24 + 8 + + + b71d0928-4d0d-41bf-8fb5-c1b2b8f39b7e + e688d880-c0f0-42de-9e2f-efa5620879d4 + 299acfd6-b7e2-4e08-b753-c450be050266 + 5 + 7 + + + b50e2d20-b3e0-4f78-900e-fc45694b62a2 + a285b49d-e590-4a03-932b-6c8e2c62b56d + 299acfd6-b7e2-4e08-b753-c450be050266 + 19 + 12 + Left + + + a9e9444c-90d8-40b4-8bc4-15b6888ae1e5 + 299acfd6-b7e2-4e08-b753-c450be050266 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 24 + 9 + + + 35121752-41a4-4051-bc39-4467ae67a86c + 00000000-0000-0000-0000-000000020101 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 15 + 10 + + + 41a587a3-669b-43ea-9638-639bd788d0fe + efa8c263-48a7-4605-9dcc-8c6c3c4cfa4a + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 22 + 5 + Right + + + 3ca7bb8f-66ae-4625-bf39-baf367fec6d6 + 299acfd6-b7e2-4e08-b753-c450be050266 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 19 + 9 + + + 781dec44-e736-470f-866e-edbd9b002fd3 + d5999d18-6060-45a9-816c-648fabeb55e6 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 31 + 9 + + + 4a844650-207c-49ba-8fd1-7aeccb260578 + 33f62b27-36d1-4808-8c88-b5c2aae1b581 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 22 + 16 + Left + + + d1e7414f-2d5b-4901-8cdf-75440f73a320 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 15 + 10 + + + 5a2a3194-834e-4199-a3f8-c52695890612 + 905d858b-cfd9-46a2-a057-c519d6c9e559 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 20 + 12 + + + 5fb3e87e-0093-4270-b3f1-d8bc09eb10cf + dea1e7b0-e1e2-4e55-aaf6-6e24628ff31b + c3fc1c75-abc0-4507-886e-c4b544c5929d + 12 + 12 + + + eb2ec7f5-d325-4949-97ef-9d56237d83f0 + 9ef8502e-6d79-48a7-a745-4b00331e527d + c3fc1c75-abc0-4507-886e-c4b544c5929d + 20 + 10 + + + 0a5583fa-6c54-44f7-a7c6-5ee853129ebd + 3e51679f-92f6-4ab8-87d0-6b18500867d5 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 15 + 15 + Left + + + c572908a-9777-4db0-8e0b-89d28d8b5b90 + c3fc1c75-abc0-4507-886e-c4b544c5929d + fa3a03ab-3c04-485f-a3c9-042111811c4a + 44 + 16 + + + 06ff951d-4b72-4839-84ba-1700293c3b9f + c3fc1c75-abc0-4507-886e-c4b544c5929d + fa3a03ab-3c04-485f-a3c9-042111811c4a + 34 + 16 + + + 541cac98-fc43-4641-9bbd-d0fe5d0734d0 + c3fc1c75-abc0-4507-886e-c4b544c5929d + fa3a03ab-3c04-485f-a3c9-042111811c4a + 39 + 16 + + + a5375bcb-c89e-4fb9-a834-86542f47e8b4 + c3fc1c75-abc0-4507-886e-c4b544c5929d + fa3a03ab-3c04-485f-a3c9-042111811c4a + 14 + 16 + + + 65a47725-ecea-4a15-9e1e-3a81721d3a5b + c3fc1c75-abc0-4507-886e-c4b544c5929d + fa3a03ab-3c04-485f-a3c9-042111811c4a + 19 + 16 + + + bef22d65-f67b-49c3-a6bd-a3122b9808ef + eb4b7af6-14a3-4724-9044-1dfc42ef2705 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 57 + 10 + + + 03b64229-c16f-4e5a-b63c-875a09547308 + c3fc1c75-abc0-4507-886e-c4b544c5929d + fa3a03ab-3c04-485f-a3c9-042111811c4a + 29 + 16 + + + ea18d5bf-0fec-44ef-921b-66f863d304b9 + 52d2a7ae-cd5c-4a5e-a92d-eb2dd249c9bc + fa3a03ab-3c04-485f-a3c9-042111811c4a + 5 + 20 + + + b05b897e-f577-415c-b0ed-516d7cdcc48b + f00cc385-0b10-46c5-ac47-ae9d2b3464d7 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 5 + 16 + + + 72e4fe97-f8de-4e2c-90bf-fb88c4de5915 + c6c9fb96-de72-4d1b-92f4-a9192c9d67de + fa3a03ab-3c04-485f-a3c9-042111811c4a + 54 + 6 + Down + + + 60a9a4da-2df9-43b1-8be9-fe6dd02b098c + d53476dc-fcbb-42fe-9c2b-781ba4cbb0b3 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 5 + 18 + + + cd402809-02c5-4c8b-aec8-965ce2161988 + c3fc1c75-abc0-4507-886e-c4b544c5929d + fa3a03ab-3c04-485f-a3c9-042111811c4a + 24 + 16 + + + dca54457-4af5-4c55-b56f-70f1a488b2c1 + c3fc1c75-abc0-4507-886e-c4b544c5929d + fa3a03ab-3c04-485f-a3c9-042111811c4a + 49 + 16 + + + bc9e38fa-5e04-4cdf-af43-703ff2e9b6f8 + aa935336-2235-4775-9284-3b5f69282b22 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 10 + 12 + + + 1bbd13f5-bcca-4a9e-932d-406975b6938a + fa3a03ab-3c04-485f-a3c9-042111811c4a + 1fae8778-f915-4e77-8bcc-8cae92219887 + 7 + 8 + + + 526856e2-c39b-407b-b379-e4b422b2b6f2 + ba46bbb3-5c3f-45ee-9435-7b57a098ab10 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 12 + 9 + Down + + + 29baf06b-1a58-462c-a969-91a25e885aa8 + 00000000-0000-0000-0000-000000020101 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 8 + 4 + Down + + + 8ca212a8-076d-400b-bc25-f654c1cd2c98 + f72959d5-18ba-4efc-b1e4-fcca76df2c5c + 1fae8778-f915-4e77-8bcc-8cae92219887 + 3 + 8 + + + 08a8d1b4-afb6-46ac-9b52-f6f6a449b8e6 + 00000000-0000-0000-0000-000000010000 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 3 + 16 + + + 70b48299-6950-4e5f-a2b0-a7d4e9e115dd + 6228e567-640a-407b-a076-c816361f75d4 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 15 + 13 + + + cf7a2446-a5c3-4b99-b427-d51b170de7f9 + bfa87be6-d5b7-4270-92a0-00a02083c2d9 + 113983b6-1055-4f58-8d8e-031737abac1b + 3 + 5 + + + ec576fd7-363c-4f6f-bfa3-9918d35a0ef3 + f3a63e93-a141-4848-9a3b-80b04f281ca5 + 113983b6-1055-4f58-8d8e-031737abac1b + 13 + 9 + + + 5c617cf3-c381-4482-b78b-28227e61e51d + 00000000-0000-0000-0000-000000010000 + 113983b6-1055-4f58-8d8e-031737abac1b + 3 + 13 + + + 0d712391-df61-44d7-b90d-56b4c4e6ffd8 + 1a2ed47e-66e2-43d9-9665-f16f88ba6b0c + 113983b6-1055-4f58-8d8e-031737abac1b + 26 + 14 + + + 3f28eb96-b83a-4a86-8080-a831ecf47c93 + 9e2f1732-790b-482c-9d8e-594f34765d20 + 113983b6-1055-4f58-8d8e-031737abac1b + 12 + 6 + Down + + + 46788803-077a-41f1-8600-357f4b245d6c + 00000000-0000-0000-0000-000000020101 + 113983b6-1055-4f58-8d8e-031737abac1b + 8 + 1 + Down + + + 7127319a-729b-4df3-b5ed-b6834a30308b + 9a2838ce-2c7f-4c0d-a4e0-f65b4ac875bc + 113983b6-1055-4f58-8d8e-031737abac1b + 9 + 18 + + + e69de09f-68ef-4db9-99c8-2753a25dd90a + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 43 + 20 + + + c2166798-6164-4a91-89d9-b98a46e56f2f + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 33 + 20 + + + 88ad0fb4-61d5-47ae-9044-edf696fad7c4 + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 8 + 20 + + + d7c07966-85dc-4ff4-a4d1-6de4d222cec7 + 1a8a57a2-1742-4bbb-a317-29f455b17c9d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 1 + 18 + + + 552a880c-c7a7-465e-b909-bedc329e6465 + 00000000-0000-0000-0000-000000040200 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 4 + 20 + + + 78afd381-85c0-4541-897a-3fce3f46ea29 + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 38 + 20 + + + 8dddcad3-74f1-4b8e-96b5-8f641960e930 + 2f388674-0d48-4b4d-b22c-61dfc0899fac + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 83 + 11 + + + 74451faa-9f9e-40e1-b5d2-c1f6498fae0a + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 23 + 20 + + + efb4cedf-063b-4dbd-891b-a289c33e11fa + c82fd9ca-6ac4-450d-9601-9ca1803ead11 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 1 + 22 + + + eeae9995-e120-47fd-ac98-2a1f40733fac + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 18 + 20 + + + a1786b81-b65b-4fb5-8160-62ae9661b606 + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 13 + 20 + + + 0689b12d-67b8-4ca2-9829-8b44bf12e80f + df51f392-2baf-442f-a069-6a7f420b7d9a + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 1 + 24 + + + 6ea15266-f256-4623-a1be-4a141e6aec7d + a218fe54-6032-4545-9244-77de0c5877bd + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 1 + 20 + + + 114abcb0-5538-4105-a1c1-a8c5d405aa57 + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 28 + 20 + + + 08619dd9-de8d-40b1-91be-f1e7a0f513ab + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 48 + 20 + + + 961f070d-4b08-4b2e-b5ce-ef2047bc05f2 + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 58 + 20 + + + 6b1c818d-6fec-4029-a5c0-a6b2dc9a342f + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 53 + 20 + + + d1b89b8d-9766-46c5-bf56-ad6b8df06f6c + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 73 + 20 + + + a9454085-0ebe-40c6-ac7a-17fc084cd887 + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 63 + 20 + + + 8c63212b-a27f-45cb-8a44-ddc46ca54bbe + c3fc1c75-abc0-4507-886e-c4b544c5929d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 68 + 20 + + + 4e34e314-1a7d-4b30-a878-9435e8e2cca7 + cc768a97-db83-4462-8f8c-dcba35ac5c56 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 80 + 4 + Down + + + 55ad8af0-1151-46c9-9af7-e96f7881bfb4 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 113983b6-1055-4f58-8d8e-031737abac1b + 7 + 5 + + + 59bb2af4-4c37-4b5d-a0ab-474ec7195d58 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 12 + 11 + 12 + 10 + + + 0d62a9f6-20c9-4e73-b39f-8aae9e8d3b54 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 12 + 10 + 13 + 10 + + + 4c8700f0-f01a-46b0-8155-a401b8c40902 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 16 + 14 + 18 + 14 + + + 9963e06c-3f09-4e72-b504-851d0e9cd1aa + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 13 + 9 + 11 + 9 + + + f44ea838-62d5-4fea-87a9-fa0231000218 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 13 + 14 + 11 + 14 + + + e507c2d8-4d37-4bb7-bdaa-95e8eff4ded4 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 18 + 10 + 12 + 12 + + + 7354eae7-dec2-4cad-8be0-2095abdc1d77 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 16 + 9 + 18 + 9 + + + 4287aedd-76de-4203-9af5-c4f3b8381bf1 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 18 + 13 + 12 + 11 + + + 2da96f26-d508-45cb-9bfb-5da3d0dd1b29 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 18 + 14 + 18 + 13 + + + 6f3bd429-e030-485b-8852-3dbcb537520b + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 12 + 12 + 12 + 13 + + + f8daac12-6dc2-4810-939f-272283a831b9 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 12 + 15 + 12 + 16 + + + 39bec303-3688-41f1-a73a-42608a3b01db + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 18 + 9 + 18 + 10 + + + 4545369d-6738-47bf-9ed7-e06e1f057d4a + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 12 + 13 + 13 + 13 + + + b6bb9fd7-b0ca-4acd-a10c-7c6001fcae2c + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 18 + 14 + 19 + 14 + + + 787b167c-23c9-472b-a895-602b04ad08e2 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 12 + 8 + 12 + 7 + + + 49061561-8b6a-40f9-8a12-62ef74217fa1 + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 13 + 15 + 12 + 15 + + + 4d1a447b-ceb8-4f98-b468-c6100d576d6c + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 18 + 9 + 19 + 9 + + + ae912960-07a5-43ab-8cca-2129435040ad + 4be7afd3-d19c-4818-9855-f7d539d7a999 + 13 + 8 + 12 + 8 + + + 183a9adc-d829-4ff2-b8f2-eb7e086275a6 + 299acfd6-b7e2-4e08-b753-c450be050266 + 10 + 5 + 9 + 5 + + + b8d26776-1f58-4d09-8972-7275d26b602c + 299acfd6-b7e2-4e08-b753-c450be050266 + 13 + 7 + 13 + 8 + + + c9c1570b-9c7a-42b5-a8b2-21ff30c8596f + 299acfd6-b7e2-4e08-b753-c450be050266 + 14 + 7 + 13 + 7 + + + b0bbcb8d-ca88-443b-b58b-c961a9c441aa + 299acfd6-b7e2-4e08-b753-c450be050266 + 9 + 11 + 7 + 11 + + + 6b52f941-cc49-4652-8191-32bcbae0694e + 299acfd6-b7e2-4e08-b753-c450be050266 + 19 + 9 + 18 + 9 + + + c16fb0d6-f9b1-4033-b289-148db743d860 + 299acfd6-b7e2-4e08-b753-c450be050266 + 18 + 7 + 19 + 7 + + + 945ac09b-acaf-4cc7-9787-4e7591f23825 + 299acfd6-b7e2-4e08-b753-c450be050266 + 18 + 9 + 18 + 10 + + + ba0500f6-e59c-430f-ba47-5195e0cf096c + 299acfd6-b7e2-4e08-b753-c450be050266 + 17 + 10 + 18 + 10 + + + 72dd3f70-360e-4bb9-a90c-8eeb3655a308 + 299acfd6-b7e2-4e08-b753-c450be050266 + 17 + 6 + 18 + 6 + + + 8534b900-ff25-4755-af53-c6ed11dba924 + 299acfd6-b7e2-4e08-b753-c450be050266 + 7 + 8 + 13 + 8 + + + c07380a2-d4ba-47a8-8483-da53a712ee8f + 299acfd6-b7e2-4e08-b753-c450be050266 + 14 + 9 + 13 + 9 + + + a90a35de-4f51-487c-9636-6a002717b857 + 299acfd6-b7e2-4e08-b753-c450be050266 + 14 + 11 + 9 + 11 + + + 93432f83-a2e7-4a8d-9840-d5e7fcf4d346 + 299acfd6-b7e2-4e08-b753-c450be050266 + 20 + 6 + 20 + 4 + + + 76a5f3a0-44ce-471e-8bec-e5a4ac9a5912 + 299acfd6-b7e2-4e08-b753-c450be050266 + 22 + 9 + 24 + 9 + + + 103c061c-180d-4800-9231-36ca764f21bc + 299acfd6-b7e2-4e08-b753-c450be050266 + 20 + 10 + 20 + 12 + + + dc573905-6d66-4ab0-b64c-b5de6be0e211 + 299acfd6-b7e2-4e08-b753-c450be050266 + 13 + 8 + 13 + 9 + + + 005418e2-9bb2-4a67-b469-4066a6e1d234 + 299acfd6-b7e2-4e08-b753-c450be050266 + 13 + 5 + 14 + 5 + + + f52e5e3b-0013-4b84-bf1b-d1048b5c0365 + 299acfd6-b7e2-4e08-b753-c450be050266 + 9 + 5 + 9 + 11 + + + 6ae19e5b-8efa-442d-a6f6-d4dce22b3eef + 299acfd6-b7e2-4e08-b753-c450be050266 + 22 + 7 + 24 + 7 + + + fdf43993-3a7e-4b50-afc1-57f93fce6ee9 + 299acfd6-b7e2-4e08-b753-c450be050266 + 18 + 6 + 18 + 7 + + + ad6b3522-8821-4eaa-946b-4f2ae223d3f5 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 13 + 10 + 19 + 10 + + + b6752f2b-160c-42c8-badb-30fa5005ad3c + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 22 + 10 + 24 + 10 + + + 6a85b61e-7b3f-44fd-b4be-b6d7927ea4a4 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 23 + 14 + 23 + 12 + + + 928324b8-f80d-4ed8-afc5-713dc5b01f25 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 19 + 12 + 18 + 12 + + + e18934b5-962b-47ee-a297-f85e52f6e7bb + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 23 + 8 + 20 + 8 + + + c96468b4-c777-4123-ab1a-3fbabc208ef4 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 23 + 8 + 25 + 8 + + + bba035ed-4184-480d-a213-e97e0ae98659 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 13 + 12 + 14 + 12 + + + 815947d7-4f54-42db-ad89-e9088f12d7cc + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 15 + 12 + 14 + 12 + + + 27382f40-c8d0-4242-a79a-3895686f1b2c + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 27 + 10 + 31 + 10 + + + 04fbf501-d5c4-4e8d-a8ed-20173fa18e63 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 14 + 12 + 14 + 14 + + + b5d77a31-3e33-40be-87b4-e9a5560e0e5d + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 23 + 12 + 24 + 12 + + + 639d04de-ca1c-4359-a9bb-e44d13e4ed91 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 20 + 8 + 20 + 9 + + + 2a246832-655e-42d7-818d-1928f640ca9a + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 23 + 7 + 23 + 8 + + + 922ddffd-4e81-4eb9-a106-1ed0bfc4feba + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 23 + 16 + 23 + 15 + + + 5ab9ba80-5144-4fd8-bb79-598cbdf2ce64 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 20 + 13 + 20 + 15 + + + 9aec5b8c-8beb-42df-ac24-60ef514f3b98 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 27 + 12 + 31 + 12 + + + d9a11992-8421-4a41-9a8c-59332d503daa + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 25 + 8 + 25 + 9 + + + df401890-baf9-410e-87ec-cbd5140c9c87 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 23 + 15 + 20 + 15 + + + 1d68526e-4e48-44ab-8dc0-d5d82e524429 + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 25 + 15 + 23 + 15 + + + c7cc2b23-cb99-41a7-9a23-642afe63c23f + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 14 + 14 + 23 + 14 + + + d98038ac-355f-419c-8f4e-d7117697a10c + aaf4821e-2320-4350-bcd9-a2e9c60a3d74 + 25 + 13 + 25 + 15 + + + a89a60ca-3e13-49ee-af40-fe7fe4aaf15e + c3fc1c75-abc0-4507-886e-c4b544c5929d + 18 + 13 + 19 + 13 + + + 35732552-7232-4129-85fa-1a5d566cd638 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 15 + 13 + 14 + 13 + + + f9aa2586-f0e4-48c0-b310-0f6522a843e9 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 14 + 9 + 14 + 11 + + + bfa6fb0f-2bac-4700-881d-aa3b12c3d6c2 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 19 + 13 + 19 + 9 + + + 1965a57e-83f6-4ee6-8f21-3d3c28aa3796 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 19 + 9 + 14 + 9 + + + 076b2c9c-bf19-4ab1-b453-feeef45f991f + c3fc1c75-abc0-4507-886e-c4b544c5929d + 19 + 13 + 20 + 13 + + + 9b84e7c5-6029-4402-985b-da2156f8bdd0 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 20 + 11 + 18 + 11 + + + 277c38a3-d616-4dc9-8754-6742380ca4bb + c3fc1c75-abc0-4507-886e-c4b544c5929d + 16 + 14 + 16 + 15 + + + 4cd5abec-ac70-4d53-83bb-5e63df1945f4 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 14 + 11 + 15 + 11 + + + 0e15c0eb-b8c5-4132-916f-9de307928615 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 16 + 8 + 16 + 10 + + + 55a65560-57cc-4978-aca5-ac56ed4526aa + fa3a03ab-3c04-485f-a3c9-042111811c4a + 54 + 12 + 28 + 12 + + + 6afdea19-df7e-439a-bd26-4c02ee4727a9 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 48 + 19 + 48 + 18 + + + 3b3084c7-f5e3-4271-b87b-135c9285c61f + fa3a03ab-3c04-485f-a3c9-042111811c4a + 35 + 20 + 35 + 21 + + + cde070b2-adf0-46a7-a60d-43c620966628 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 37 + 19 + 38 + 19 + + + 49d1af9c-9dba-4566-b1e9-c4e8fcdcd73e + fa3a03ab-3c04-485f-a3c9-042111811c4a + 32 + 19 + 33 + 19 + + + 413abbdd-16de-4472-b13b-3ebe7bbf357a + fa3a03ab-3c04-485f-a3c9-042111811c4a + 32 + 17 + 33 + 17 + + + c7c27a5b-42be-42e6-b28e-0e8e6b69102c + fa3a03ab-3c04-485f-a3c9-042111811c4a + 28 + 19 + 28 + 18 + + + e2f094d8-3183-441f-982e-6ad928dd6c81 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 23 + 19 + 23 + 18 + + + e74a4cdd-7470-4db3-ba25-6d6dac38a84f + fa3a03ab-3c04-485f-a3c9-042111811c4a + 22 + 19 + 23 + 19 + + + 4e6be037-5c03-49be-adf5-355a22a915ce + fa3a03ab-3c04-485f-a3c9-042111811c4a + 18 + 17 + 18 + 14 + + + f7c9396e-f739-4b45-a545-65cad2f16107 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 30 + 16 + 30 + 15 + + + 8cbe5328-87b4-4c6e-a351-a334bd2502b1 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 37 + 17 + 38 + 17 + + + d6e83435-6645-45d6-adbf-170389a7c2fa + fa3a03ab-3c04-485f-a3c9-042111811c4a + 23 + 18 + 24 + 18 + + + c1671db8-3234-4c02-95e6-3186f474babc + fa3a03ab-3c04-485f-a3c9-042111811c4a + 18 + 19 + 18 + 18 + + + 1d32a42b-d371-4675-8a6d-54a2d5f4bcb7 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 17 + 19 + 18 + 19 + + + 3be97d43-070b-41b0-9103-7233269ee561 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 17 + 17 + 18 + 17 + + + 8e91b154-ff07-4ccb-b2c7-2f9d79197dc0 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 28 + 17 + 28 + 12 + + + 5d647c84-ca37-4c8b-8be6-5d4588277986 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 28 + 18 + 29 + 18 + + + 64f1b4a2-f43a-41b7-b4b1-46b30cb800be + fa3a03ab-3c04-485f-a3c9-042111811c4a + 27 + 19 + 28 + 19 + + + 2c788b4c-85e7-48d1-ae83-ba84b2852111 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 27 + 17 + 28 + 17 + + + 38b8066b-5206-4084-a07b-7dad66f1f653 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 33 + 19 + 33 + 18 + + + c8863bfa-c8af-4620-ada8-6d10d4e75c7b + fa3a03ab-3c04-485f-a3c9-042111811c4a + 33 + 17 + 33 + 11 + + + cf3b4015-319b-4aec-be17-bf67d50fced0 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 23 + 17 + 23 + 13 + + + 2a186ba2-92e7-43a5-9b1f-fa6d7c1dba65 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 38 + 19 + 38 + 18 + + + 69c85f1a-00ef-4712-82e8-4dea1748149c + fa3a03ab-3c04-485f-a3c9-042111811c4a + 25 + 20 + 25 + 21 + + + 1fc62acd-d527-4d76-a01d-8d50eba46aa0 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 18 + 18 + 19 + 18 + + + 4d23490f-b473-490d-a94f-57f6cabb21e9 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 43 + 18 + 44 + 18 + + + 96c56e42-4b9e-4377-b243-7aa32f7975b0 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 7 + 21 + 15 + 21 + + + 027ac605-bd6d-4405-bee8-c5080905e7c2 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 48 + 17 + 48 + 8 + + + 77e7c53a-ec05-42b3-b3bf-87018de0d905 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 42 + 19 + 43 + 19 + + + fe657aff-28db-4adc-af00-9c1d33d96ce2 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 47 + 19 + 48 + 19 + + + 56899e2e-6876-453b-8d97-0ac1f18cb5e1 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 43 + 17 + 43 + 9 + + + ea5c7b36-6308-4e02-851c-e7e1c767ad26 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 48 + 18 + 49 + 18 + + + 932fcd74-0e90-4743-84bb-cad32198542d + fa3a03ab-3c04-485f-a3c9-042111811c4a + 47 + 17 + 48 + 17 + + + 539c34e0-5e5a-4872-911b-c7a7bad4c421 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 45 + 20 + 45 + 21 + + + 55d2d48d-76b9-4112-ab23-f91199756a18 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 38 + 18 + 39 + 18 + + + 9d50c051-189c-4f3a-b5ee-f34128c04656 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 53 + 17 + 53 + 7 + + + 21995f9c-bffb-4e14-b3f8-9e49a7ca4d46 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 40 + 20 + 40 + 21 + + + 1d533aad-85a2-490f-b457-78bef30f0300 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 33 + 18 + 34 + 18 + + + daef695c-719b-457b-a4c8-94762e7f1b62 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 43 + 19 + 43 + 18 + + + d5aef050-bd15-4aa7-a7b2-24b22a6c2349 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 15 + 20 + 15 + 21 + + + cf89d7ef-551d-44f9-9c8c-7e9addc075f8 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 50 + 20 + 50 + 21 + + + 8d27ddab-0c48-4da2-b9be-4cfc6b1c8fe0 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 40 + 21 + 45 + 21 + + + c38ab658-34f0-4b20-99ea-67a90c5a38e5 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 40 + 16 + 40 + 15 + + + 191c2d71-f9fe-4374-85aa-a74ed48d034f + fa3a03ab-3c04-485f-a3c9-042111811c4a + 30 + 21 + 35 + 21 + + + e25537b0-a76a-4dec-9ab3-9f775e76b044 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 35 + 21 + 40 + 21 + + + ca562924-2dec-4793-8e2e-6dfbf8722282 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 15 + 21 + 20 + 21 + + + d5574a37-930a-4b2f-b247-141cad4bf75b + fa3a03ab-3c04-485f-a3c9-042111811c4a + 20 + 21 + 25 + 21 + + + 1a2a33fa-d10d-4570-853f-fc14ea774f7e + fa3a03ab-3c04-485f-a3c9-042111811c4a + 45 + 21 + 50 + 21 + + + 2a0562df-b07d-45e1-bb08-8503748047a8 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 20 + 20 + 20 + 21 + + + 7ed900e8-f76a-4026-ba1e-7087ce37efc1 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 20 + 15 + 25 + 15 + + + 4c2c3298-55a9-422d-922b-7201da248185 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 15 + 16 + 15 + 15 + + + 20996811-68e9-4a07-9c94-460f3f534236 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 50 + 16 + 50 + 15 + + + 9948bd7d-2bc6-45c5-91cc-c4f0062aeac2 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 30 + 15 + 35 + 15 + + + ff103e35-1465-4fb2-9ef6-318ba66b6a5f + fa3a03ab-3c04-485f-a3c9-042111811c4a + 20 + 16 + 20 + 15 + + + 7a19dca2-5c0b-4d44-8692-96f368e37a14 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 25 + 16 + 25 + 15 + + + 558d9c17-7649-42ad-8a0b-c221687e3e6f + fa3a03ab-3c04-485f-a3c9-042111811c4a + 35 + 15 + 40 + 15 + + + 95dd297f-9bc7-4a60-888d-02fc9346fb81 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 15 + 15 + 20 + 15 + + + 3653d7d0-3058-4438-907c-927c3d6dee49 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 7 + 15 + 15 + 15 + + + ff6b033b-1437-4a91-89e8-2bd41d3f5666 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 35 + 16 + 35 + 15 + + + 065af8cb-7d4b-4d6a-bc0d-00b22ddcf6ab + fa3a03ab-3c04-485f-a3c9-042111811c4a + 54 + 14 + 18 + 14 + + + 6ff0c3b5-f236-4112-9d1b-b0c9a4b63d37 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 55 + 11 + 57 + 11 + + + acd1a24a-c2da-4c61-9253-c0742f0d8dbc + fa3a03ab-3c04-485f-a3c9-042111811c4a + 30 + 20 + 30 + 21 + + + 92c0e72a-384d-4e54-949c-c8980157fa5b + fa3a03ab-3c04-485f-a3c9-042111811c4a + 25 + 15 + 30 + 15 + + + b5ea9bea-329a-45d7-b04b-d02c43931e3a + fa3a03ab-3c04-485f-a3c9-042111811c4a + 23 + 13 + 54 + 13 + + + 7d8f3aaa-274e-45e9-8880-b5f1f44e0421 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 45 + 15 + 50 + 15 + + + 541365c0-9263-40e8-a43f-bde8e148d432 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 33 + 11 + 54 + 11 + + + 4ea1bd94-ff30-4dc1-8c4b-f4061110e884 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 54 + 10 + 38 + 10 + + + a4e2ff60-1dd0-42de-9bdf-9b2e6d3214b1 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 42 + 17 + 43 + 17 + + + 60ef8541-8a37-41ce-8f25-bf89f7dbd2b5 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 11 + 18 + 14 + 18 + + + 115f6c19-d1a0-4604-86b2-853fbe478a8a + fa3a03ab-3c04-485f-a3c9-042111811c4a + 43 + 9 + 54 + 9 + + + 9b65ca65-21ab-4450-8245-587b2a7511c2 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 54 + 8 + 48 + 8 + + + f600c815-f55b-46f2-a618-03bb5b90c7a8 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 40 + 15 + 45 + 15 + + + 78c88615-1748-43f9-89e6-69806f6547c9 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 7 + 17 + 8 + 17 + + + 6d8746ab-60cf-4a07-9517-3f775bf3800a + fa3a03ab-3c04-485f-a3c9-042111811c4a + 7 + 19 + 8 + 19 + + + 2c73027e-59d8-448b-a94b-fae839ee3c30 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 38 + 10 + 38 + 17 + + + 6ff5c4fe-347d-4b6e-96f0-994d50310cce + fa3a03ab-3c04-485f-a3c9-042111811c4a + 53 + 7 + 54 + 7 + + + 65981196-c1ff-4597-b4b8-df2d91eb833f + fa3a03ab-3c04-485f-a3c9-042111811c4a + 52 + 17 + 53 + 17 + + + 87e19679-3212-4612-aaf0-cf97cf0cbd83 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 25 + 21 + 30 + 21 + + + 2e4aa8bf-7a56-46f0-969d-8b1342078f70 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 45 + 16 + 45 + 15 + + + 875702cd-2300-4b43-8638-8c47980f3d01 + fa3a03ab-3c04-485f-a3c9-042111811c4a + 22 + 17 + 23 + 17 + + + 2deb3d7a-526c-469c-8c09-cbaab8af6407 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 10 + 10 + 11 + 10 + + + 444d5d31-c3e3-4a75-82e3-2957d8a6f1fd + 1fae8778-f915-4e77-8bcc-8cae92219887 + 11 + 10 + 12 + 10 + + + 5cbe4aa1-9c5c-4928-8513-14c20a0b4644 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 11 + 10 + 11 + 6 + + + b73a5a2c-d560-4a64-a091-992e82068ca0 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 10 + 6 + 11 + 6 + + + e4b3c4a6-ef17-4155-8626-ab69c46e429e + 1fae8778-f915-4e77-8bcc-8cae92219887 + 7 + 6 + 6 + 6 + + + aad178e2-6f5e-4389-a66e-6eb0a9d55b75 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 5 + 9 + 7 + 9 + + + bb5f5f1c-3020-4365-b56d-311753f6d0d8 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 8 + 12 + 8 + 13 + + + e8e956e3-1583-4604-98d0-1d5631a60254 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 7 + 10 + 6 + 10 + + + 9e300212-8ec9-4a2b-89a0-0b731139b14f + 1fae8778-f915-4e77-8bcc-8cae92219887 + 7 + 11 + 6 + 11 + + + f988df75-338d-428e-af2b-75d0d86c66b3 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 6 + 6 + 6 + 10 + + + b7bb2d6a-2540-4fb4-a33c-d206acc710f7 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 8 + 13 + 10 + 13 + + + b9d325d3-8d3c-45a7-ba69-964c3ee04fc9 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 8 + 13 + 8 + 15 + + + 9efc23f5-bdb1-48ce-95a0-c90bd138220d + 1fae8778-f915-4e77-8bcc-8cae92219887 + 8 + 15 + 10 + 15 + + + 0a12ed9c-04e7-4039-a216-b776bac5668e + 1fae8778-f915-4e77-8bcc-8cae92219887 + 6 + 11 + 6 + 17 + + + 854d3d04-2a42-4063-badd-1cd9a0f81b5d + 1fae8778-f915-4e77-8bcc-8cae92219887 + 6 + 17 + 12 + 17 + + + d5c13555-dd02-4290-996f-5509b6be8cc6 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 12 + 16 + 12 + 17 + + + 01f3ffc4-0f21-4119-b0bc-f469fc71c436 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 5 + 17 + 6 + 17 + + + fd2276a5-47b6-4b19-834e-ce5654b77de4 + 1fae8778-f915-4e77-8bcc-8cae92219887 + 14 + 14 + 15 + 14 + + + 742d7d14-ff69-490f-8a2f-e5e5583d1ae3 + 113983b6-1055-4f58-8d8e-031737abac1b + 11 + 7 + 11 + 3 + + + aaf0ac7d-71e5-4b81-8a1e-8676fc915c43 + 113983b6-1055-4f58-8d8e-031737abac1b + 6 + 3 + 6 + 7 + + + 8e4a150e-455c-4580-b17e-b071a3632812 + 113983b6-1055-4f58-8d8e-031737abac1b + 5 + 6 + 7 + 6 + + + 24f29f3b-4470-4b61-b107-cc8bf6a52973 + 113983b6-1055-4f58-8d8e-031737abac1b + 8 + 9 + 8 + 10 + + + e2442ac5-dc2a-4f9c-8dc4-6fa84d8e8244 + 113983b6-1055-4f58-8d8e-031737abac1b + 10 + 7 + 11 + 7 + + + a04c5e91-bd73-49c9-a6a5-ccd2894cd1cd + 113983b6-1055-4f58-8d8e-031737abac1b + 11 + 7 + 12 + 7 + + + 88a7c025-e62f-4ac6-9d21-0f2b3096050a + 113983b6-1055-4f58-8d8e-031737abac1b + 10 + 3 + 11 + 3 + + + 19b36568-7f22-4bbb-b13c-c213bb4bae33 + 113983b6-1055-4f58-8d8e-031737abac1b + 7 + 3 + 6 + 3 + + + 10204b21-977c-47a5-8f80-f28bb570d65d + 113983b6-1055-4f58-8d8e-031737abac1b + 7 + 7 + 6 + 7 + + + 1567875f-d691-4183-af7a-dccaca18fc29 + 113983b6-1055-4f58-8d8e-031737abac1b + 7 + 8 + 6 + 8 + + + 6bb4eacc-d0f1-4568-b1d2-23d57c2746bf + 113983b6-1055-4f58-8d8e-031737abac1b + 5 + 14 + 6 + 14 + + + 42892d4c-51b0-4644-8069-d075c7f4c7b2 + 113983b6-1055-4f58-8d8e-031737abac1b + 8 + 10 + 13 + 10 + + + 69c99145-5cb6-405f-87e2-33aa0ad2f2ea + 113983b6-1055-4f58-8d8e-031737abac1b + 25 + 15 + 26 + 15 + + + fad8bb94-8cb6-492d-8403-2f6274df8f5d + 113983b6-1055-4f58-8d8e-031737abac1b + 6 + 8 + 6 + 14 + + + 1d922798-6a6e-4d09-9a93-e78a880d4026 + 113983b6-1055-4f58-8d8e-031737abac1b + 12 + 20 + 13 + 20 + + + 09f2c57c-d949-45eb-a135-4d060ba63c9d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 32 + 14 + 32 + 21 + + + d50a590b-850c-448a-a3ac-4b68afe8a314 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 44 + 24 + 44 + 25 + + + 16f8fd3c-960a-4def-8e24-b97267b00ad7 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 47 + 21 + 47 + 11 + + + 038d036e-cb61-4d07-af64-98255421d140 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 32 + 23 + 32 + 22 + + + 09579764-87f3-4edc-a4db-626d59d172f4 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 11 + 21 + 12 + 21 + + + ea47bfe8-9986-4aed-8430-b1538c4cd67b + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 24 + 20 + 24 + 19 + + + f9644cd6-3f78-47ba-8fe9-32d517b0a631 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 16 + 23 + 17 + 23 + + + b8cda9e5-a16f-4969-b6a3-76e2dbbf2762 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 22 + 23 + 22 + 22 + + + dab28da8-4204-4a05-a21c-ff9c09331ad6 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 42 + 23 + 42 + 22 + + + 16d4a4d4-b6ab-48f5-8884-79f31d077641 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 29 + 24 + 29 + 25 + + + a63afa05-b748-4015-bae4-0626a8d04a36 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 31 + 23 + 32 + 23 + + + 7a902d97-c336-4d04-8830-7a8880daa8a7 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 80 + 16 + 22 + 16 + + + 2aeb2038-a330-4e33-9713-fb7e6e3f80b8 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 12 + 21 + 12 + 18 + + + 2b4e0c6a-9143-4263-ad10-c9cb79f80290 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 26 + 21 + 27 + 21 + + + 3418a676-c374-4bab-a2e5-96b110b57c1d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 31 + 21 + 32 + 21 + + + 2ca3b87a-ddce-4734-812d-3a39d56146d4 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 17 + 22 + 18 + 22 + + + 2ee9fe1b-4ee0-4a18-ac6e-3f4fc6b12e66 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 26 + 23 + 27 + 23 + + + 8439aba8-99c1-43da-ab88-430d77166422 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 17 + 23 + 17 + 22 + + + c1c26353-16e0-4ec3-bbdf-c636e36d0224 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 21 + 21 + 22 + 21 + + + 7c59d6c3-efc9-4649-a4b6-910f196d542a + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 22 + 22 + 23 + 22 + + + 96578109-d4a0-48a9-8abb-82fd304b0ce0 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 21 + 23 + 22 + 23 + + + 288886a4-80d8-44bd-9de1-409e4e41a7a2 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 11 + 23 + 12 + 23 + + + 0c9b1f6f-549d-4e95-94d3-0e28a0d86188 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 27 + 23 + 27 + 22 + + + e1eae5bd-d520-4261-a30d-5afa5d654d69 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 27 + 21 + 27 + 15 + + + 6fc7ae6a-69f5-4521-8d4f-de6892492edf + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 19 + 24 + 19 + 25 + + + 4c3aa3bc-0737-4065-bb00-a10c4403ec7f + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 22 + 21 + 22 + 16 + + + e6ec9780-94a8-40f8-801c-0f187b7a64a9 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 12 + 22 + 13 + 22 + + + e3b48a30-fe21-4e55-86a9-3814e61468f3 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 41 + 23 + 42 + 23 + + + ec186d2b-ca71-42a8-bcd4-bc6fa027d0a9 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 37 + 22 + 38 + 22 + + + 54cbcc9f-f135-411d-9e3c-ab6ef50c3666 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 3 + 25 + 9 + 25 + + + bc88a504-5510-409b-a9a4-beb44d040788 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 42 + 21 + 42 + 12 + + + 2f4df975-0b5f-4151-81d7-48f45710d3b3 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 36 + 23 + 37 + 23 + + + e862f991-67cc-4423-9c20-243154b37963 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 42 + 22 + 43 + 22 + + + 84023664-81fd-40db-824f-b6595aee8ab5 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 41 + 21 + 42 + 21 + + + b076c841-8707-4dfb-8716-dd3c8aef2592 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 37 + 21 + 37 + 13 + + + 79fda8ab-64e6-4a5c-9e35-b3da10e22308 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 27 + 22 + 28 + 22 + + + c4a53b96-8c4e-4e56-8f19-dd4c4f536b6e + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 37 + 23 + 37 + 22 + + + a426e2c4-2402-471c-bfa7-7d4e9cf10009 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 32 + 22 + 33 + 22 + + + e217c0e0-fa83-4b65-8c0a-4a5b9bbfc913 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 39 + 24 + 39 + 25 + + + a9bae0ec-6718-41cb-82c2-7fabdac0792a + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 34 + 24 + 34 + 25 + + + 9e1c3e16-6f57-490f-9f9f-471e6ff2b120 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 34 + 25 + 39 + 25 + + + f555b6d8-4236-457b-930b-c5932b8d9ab4 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 17 + 21 + 17 + 17 + + + 6b509381-6d49-4ac6-819e-69e6ca721629 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 24 + 24 + 24 + 25 + + + 86b24461-8dc6-48ef-bcb2-b877f2b18a17 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 14 + 20 + 14 + 19 + + + 36d47b83-7e76-4687-a4c7-b122f84b652e + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 34 + 20 + 34 + 19 + + + 138f549f-1dde-443c-8508-0e259c0f7512 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 39 + 25 + 44 + 25 + + + ff9d2bc0-28b6-40f3-8e96-9f8f1433532d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 24 + 25 + 29 + 25 + + + 08139b1e-1458-4f21-87f3-0990634cafbd + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 29 + 25 + 34 + 25 + + + d8691aff-c7bf-4c79-a72e-ea3bf4293fd5 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 9 + 25 + 14 + 25 + + + 418e1ae7-7cf8-46cd-bef2-45b3fb2c7b85 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 14 + 25 + 19 + 25 + + + e429114c-c3a9-4b75-a397-618ee2578b10 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 14 + 19 + 19 + 19 + + + 5fc7d565-3836-40dd-8aea-a87e34c2f30e + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 9 + 20 + 9 + 19 + + + 4481a9d6-a83c-4b8d-a553-5d0e1fad9450 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 80 + 18 + 12 + 18 + + + cbdeb79a-da6d-4db1-bc7a-2afe2378b43b + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 29 + 19 + 34 + 19 + + + eb322817-7c76-4913-a766-86678510746f + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 9 + 19 + 14 + 19 + + + c819a041-0cf2-4995-a0c1-3f16e4826881 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 24 + 19 + 29 + 19 + + + 676e8fe3-70d4-4bb8-bb75-e314703e7391 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 44 + 20 + 44 + 19 + + + 80d39fd3-646f-442b-8ed0-fc4d1ef6fc63 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 19 + 20 + 19 + 19 + + + 174191c2-d943-4a30-bbc3-843f01230fc0 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 19 + 19 + 24 + 19 + + + 894af215-9642-40c8-b713-5aae5edd5545 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 29 + 20 + 29 + 19 + + + 7c2a094f-a05c-4b0b-81eb-f03907f9a773 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 36 + 21 + 37 + 21 + + + f9fbeff8-cff8-43a9-a366-1d6dfef79487 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 17 + 17 + 80 + 17 + + + cdd25f9f-2076-4022-922d-f59bbfd79616 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 39 + 19 + 44 + 19 + + + db4798c6-12c3-4427-a2b4-d420d58cb384 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 27 + 15 + 80 + 15 + + + 7738e1d3-30c5-49a9-a227-eca1a3abfc2a + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 7 + 22 + 8 + 22 + + + 810555b3-ef3c-40a2-9858-35796ed6a540 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 81 + 12 + 83 + 12 + + + 1bf8d1e1-8ea0-457d-a02d-a3886ec4c8fc + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 80 + 12 + 42 + 12 + + + 8512fcf8-8a4d-4c7a-98a1-f589a6728452 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 34 + 19 + 39 + 19 + + + bc2328f4-1588-4ef0-8316-e793edd36f5c + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 80 + 14 + 32 + 14 + + + c8d2e5b9-3598-4151-9c11-85efce0c91e2 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 47 + 11 + 80 + 11 + + + b290875b-389e-4983-a039-c56bca317c55 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 39 + 20 + 39 + 19 + + + 4e09c8d3-b7c4-40db-87e9-9ea789319314 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 16 + 21 + 17 + 21 + + + ec220df2-eaf7-4fb4-b61d-f15df8654b4b + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 3 + 23 + 4 + 23 + + + f442e736-6e06-4cc5-baed-293f765324f5 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 46 + 21 + 47 + 21 + + + b256cc2d-26f7-41eb-bbbd-70bac42c7be4 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 19 + 25 + 24 + 25 + + + 29243478-4a2b-4886-b1f2-f9b5381affce + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 37 + 13 + 80 + 13 + + + 78eaaf0a-0277-43bd-9e3d-3356bf0d1935 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 3 + 21 + 4 + 21 + + + 24a5f721-088a-4a3e-8eed-08eee2fc7f9d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 9 + 24 + 9 + 25 + + + bacae0ff-496e-48b5-bbf8-44e42667d52e + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 14 + 24 + 14 + 25 + + + de4343c3-7cdf-4983-a6e9-59111bc3d6de + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 3 + 19 + 9 + 19 + + + ab62be4b-a23d-48df-a8a7-bf9e7d074813 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 12 + 23 + 12 + 22 + + + 94fee3be-55a9-4106-a4dc-d63a93063c46 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 59 + 19 + 64 + 19 + + + b45fcba4-5d8f-4ecd-b620-47fe89960447 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 69 + 24 + 69 + 25 + + + 6ef51c61-f2dc-4544-a493-963e80cd2a55 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 56 + 23 + 57 + 23 + + + 7a9f870f-ce03-40cd-9a2f-615c0ea933b7 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 51 + 21 + 52 + 21 + + + 28c76e0d-56e2-474d-9abe-3248679cba8a + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 61 + 23 + 62 + 23 + + + a88a7976-f1bd-48b5-ab54-830f1270d098 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 72 + 23 + 72 + 22 + + + dd0bfd27-0afd-4bdc-9af0-a95641110777 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 59 + 24 + 59 + 25 + + + 284ff931-7da9-4c77-924f-f1fed76b4e0f + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 54 + 20 + 54 + 19 + + + 29cff5bd-28f7-4bae-a634-c4dd859bb928 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 74 + 24 + 74 + 25 + + + ed18c74e-0dcf-44ee-a62e-9d642bc66ed0 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 62 + 23 + 62 + 22 + + + 3e740de5-e029-4b79-b71e-aa229025bd00 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 61 + 21 + 62 + 21 + + + 5a4e82b8-6121-4a68-8eba-10a5deb2758f + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 52 + 23 + 52 + 22 + + + a8160fe9-af2a-467e-85ef-61884d56aee4 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 52 + 22 + 53 + 22 + + + 7047514f-bd8d-4ffd-8b13-9185c133599e + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 51 + 23 + 52 + 23 + + + 067b2b34-997e-4e08-8873-8db62f6d27e2 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 67 + 23 + 67 + 22 + + + 142b8acb-89bf-4a91-92cd-5efe584c981b + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 67 + 22 + 68 + 22 + + + 75883888-66a8-4b5a-82a8-bf4193d550d4 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 71 + 23 + 72 + 23 + + + be54a9ab-f0da-43db-b748-7c287e5a0d78 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 49 + 24 + 49 + 25 + + + 7bccedbc-c20a-4d54-b63c-df7f927025c9 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 72 + 22 + 73 + 22 + + + 96f22795-62f1-445d-bc19-4994105b0175 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 71 + 21 + 72 + 21 + + + c2aee4ca-07ee-414b-aab9-9ae1c0c0d160 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 64 + 24 + 64 + 25 + + + c201bf37-0599-4046-b64b-ea7412bccc50 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 57 + 22 + 58 + 22 + + + 074e5cc5-2d0d-4ffa-8f04-d82c7624d4dc + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 64 + 20 + 64 + 19 + + + 99b3d0a5-fd09-4784-9c4d-0d0428210dd1 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 57 + 23 + 57 + 22 + + + d623e89f-8518-4cd2-8ba8-ca6c949ac43c + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 66 + 23 + 67 + 23 + + + 242b2347-26b5-46f8-88e6-e032c7b4ad7e + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 62 + 22 + 63 + 22 + + + 88f0af30-ddd4-4ac8-b954-d962b1e3c262 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 69 + 25 + 74 + 25 + + + 46702009-6d02-4966-ae2d-1e68113b7503 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 54 + 24 + 54 + 25 + + + cc26ce8d-312c-4ed9-8d5e-a25aa11bd121 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 54 + 25 + 59 + 25 + + + 7f25d51b-8d96-40e9-80ff-b9d27e52e039 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 59 + 25 + 64 + 25 + + + e1a3ebdd-0c85-4157-ac96-f10c1df82ab3 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 69 + 20 + 69 + 19 + + + 69fcb08b-40cf-4e72-b9b9-d0515cbcb2c3 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 69 + 19 + 74 + 19 + + + d5612053-ac76-47fc-9e11-029a6ce10bcb + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 54 + 19 + 59 + 19 + + + 7222b352-c1a0-4a2e-a49d-298c8fb03edd + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 74 + 20 + 74 + 19 + + + 3e27635d-f8e8-4d5a-a7cb-f8675d49227e + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 49 + 20 + 49 + 19 + + + 32b8b1a0-3065-4918-b74d-30a5a98cc074 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 59 + 20 + 59 + 19 + + + a47b4439-a7ae-450c-aad2-fcab657f4a62 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 66 + 21 + 67 + 21 + + + 55ef5028-1dcf-4f7e-b077-ad8a556acef7 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 76 + 21 + 77 + 21 + + + be65e273-dc31-4266-9cab-5c0b405b9a4f + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 49 + 25 + 54 + 25 + + + 806d2eab-5177-44f1-8e60-4f19c9d1487d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 64 + 25 + 69 + 25 + + + 69a47974-d686-4393-907d-057d34d9e137 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 49 + 19 + 54 + 19 + + + 976cecda-074d-41b5-8a68-4b2f615b3d7a + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 64 + 19 + 69 + 19 + + + 437d5821-7aa7-4a2f-9ad9-d416b4c22a70 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 56 + 21 + 57 + 21 + + + 60b87f6d-8505-4d29-978d-4cd523ea552a + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 44 + 19 + 49 + 19 + + + e36d228f-e4ca-4da4-81ed-a1f41a53a478 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 44 + 25 + 49 + 25 + + + be1ce3fb-a25a-4234-81b1-6de023b0d2a3 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 46 + 23 + 47 + 23 + + + cb69208e-c3f0-4386-a8c1-fef2af2f47a2 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 47 + 23 + 47 + 22 + + + dcc8afe0-4727-487f-affa-f7da8c8f44f2 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 47 + 22 + 48 + 22 + + + a79bf14c-5820-44f9-95cd-6a3dc28c295a + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 52 + 21 + 52 + 10 + + + af00ba7f-6f99-488e-b26e-68992484be55 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 52 + 10 + 80 + 10 + + + 392742df-13ad-4e3f-9b8e-e70bc2375a41 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 57 + 21 + 57 + 9 + + + 34563f14-b798-425a-ba7a-e9b3f40a72af + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 57 + 9 + 80 + 9 + + + b5c88e47-f1e0-4ca6-89b2-7f8980f3bf23 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 62 + 21 + 62 + 8 + + + 7e768882-8b2c-41fe-a13f-f4bf83430874 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 62 + 8 + 80 + 8 + + + 19de74da-5146-4f03-ac23-1d45a901f843 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 67 + 21 + 67 + 7 + + + 79ea4912-8b25-49c0-8d2c-272ed3ca006d + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 67 + 7 + 80 + 7 + + + 97a1a07d-30e9-4ee1-8233-29d954acd189 + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 72 + 21 + 72 + 6 + + + 4bdde654-b72f-493b-8f85-e18e06e8addb + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 72 + 6 + 80 + 6 + + + 5201fca5-7e41-4815-9a88-b36e8428736b + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 77 + 21 + 77 + 5 + + + 5bdb5466-5c3e-42ec-a128-8be0c5b6b39b + ec0c2f6c-3feb-4f77-ac64-fa05d09de06a + 77 + 5 + 80 + 5 + + + 4c5dac13-7d39-4f9f-ba25-81ed885c7343 + 113983b6-1055-4f58-8d8e-031737abac1b + 8 + 10 + 8 + 20 + + + 5e707acf-83ef-4a4e-92d6-1a9139f455bd + 113983b6-1055-4f58-8d8e-031737abac1b + 8 + 20 + 9 + 20 + + + 5ee7b0e6-87f9-4a82-a100-17e9d0920222 + 113983b6-1055-4f58-8d8e-031737abac1b + 6 + 14 + 6 + 23 + + + 664a5b10-fd3a-40ad-b64d-db5df085ac4b + 113983b6-1055-4f58-8d8e-031737abac1b + 6 + 23 + 19 + 23 + + + 6735af0c-e055-4c0c-8fc0-f50533751977 + 113983b6-1055-4f58-8d8e-031737abac1b + 19 + 23 + 19 + 21 + + + a4ac438a-843b-45e0-8359-e2a06a36a525 + c3fc1c75-abc0-4507-886e-c4b544c5929d + 25 + 10 + 4 + 1 + <FlowDocument PagePadding="5,0,5,0" AllowDrop="True" NumberSubstitution.CultureSource="User" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"><Paragraph><Run xml:lang="zh-cn">toggle</Run></Paragraph></FlowDocument> + + \ No newline at end of file diff --git a/logic/vga/bingbing.bin b/logic/vga/bingbing.bin new file mode 100644 index 0000000..76cab58 Binary files /dev/null and b/logic/vga/bingbing.bin differ diff --git a/logic/vga/bingbing.jpg b/logic/vga/bingbing.jpg new file mode 100644 index 0000000..fd109ba Binary files /dev/null and b/logic/vga/bingbing.jpg differ diff --git a/logic/vga/result.act b/logic/vga/result.act new file mode 100644 index 0000000..e2777ec Binary files /dev/null and b/logic/vga/result.act differ diff --git a/snapshots/onix.jpg b/snapshots/onix.jpg new file mode 100644 index 0000000..3df0dd5 Binary files /dev/null and b/snapshots/onix.jpg differ diff --git a/x86_assembly/analysis/appendix.asm b/x86_assembly/analysis/appendix.asm new file mode 100644 index 0000000..70e6ac6 --- /dev/null +++ b/x86_assembly/analysis/appendix.asm @@ -0,0 +1,9 @@ +%use masm + +section .data + number dd 0x12345678 + +section .text +global main +main: + mov ax, [number] diff --git a/x86_assembly/analysis/assembly.c b/x86_assembly/analysis/assembly.c new file mode 100644 index 0000000..a717da9 --- /dev/null +++ b/x86_assembly/analysis/assembly.c @@ -0,0 +1,17 @@ +#include + +int main() +{ + int a = 10; + int b = 20; + int result = 30; + + // result = a + b; + asm volatile( + "movl $10, %0\n" + "movl $20, %1\n" + : "=&r"(a) // %0 + : "r"(b)); + + printf("%d + %d = %d\n", a, b, result); +} \ No newline at end of file diff --git a/x86_assembly/analysis/assembly.s b/x86_assembly/analysis/assembly.s new file mode 100644 index 0000000..1342511 --- /dev/null +++ b/x86_assembly/analysis/assembly.s @@ -0,0 +1,36 @@ + .file "assembly.c" + .text + .section .rodata +.LC0: + .string "%d + %d = %d\n" + .text + .globl main + .type main, @function +main: + pushl %ebp + movl %esp, %ebp + subl $12, %esp + movl $10, -4(%ebp) + movl $20, -8(%ebp) + movl $30, -12(%ebp) + movl -8(%ebp), %edx +#APP +# 10 "assembly.c" 1 + movl $10, %eax +movl $20, %edx + +# 0 "" 2 +#NO_APP + movl %eax, -4(%ebp) + pushl -12(%ebp) + pushl -8(%ebp) + pushl -4(%ebp) + pushl $.LC0 + call printf + addl $16, %esp + movl $0, %eax + leave + ret + .size main, .-main + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits diff --git a/x86_assembly/analysis/astring.asm b/x86_assembly/analysis/astring.asm new file mode 100644 index 0000000..dd518bb --- /dev/null +++ b/x86_assembly/analysis/astring.asm @@ -0,0 +1,112 @@ + +global memcpy +memcpy: + ; void* memcpy( void *dest, const void *src, size_t count ); + push ebp + mov ebp, esp + + mov ecx, [ebp + 16]; count loop + mov esi, [ebp + 12]; src + mov edi, [ebp + 8]; dest + + cld + rep movsb + + mov eax, [ebp + 8]; + leave + ret + + +memcmp: + ; int memcmp(const void* lhs, const void* rhs, size_t count ); + push ebp + mov ebp, esp + + mov ecx, [ebp + 16] + mov esi, [ebp + 12] + mov edi, [ebp + 8] + + cld + repz cmpsb + + mov ecx, -1 + cmovb eax, ecx + mov ecx, 1 + cmova eax, ecx + mov ecx, 0 + cmovz eax, ecx + + leave + ret + +memset: + ;void *memset(void *d1, int val, size_t len) + push ebp + mov ebp, esp + + pusha + + mov ecx, [ebp + 16]; len + mov al, [ebp + 12]; val + mov edi, [ebp + 8]; dest + + cld + rep stosb + + mov eax, [ebp + 8] + leave + ret + +memchr: + ; void* memchr(void* ptr, int ch, std::size_t count ); + push ebp + mov ebp, esp + + mov ecx, [ebp + 16]; len + mov al, [ebp + 12]; val + mov edi, [ebp + 8]; dest + + cld + repne scasb + + cmp ecx, 0 + jz .notfound + + mov eax, [ebp + 8] ; dest + mov edx, [ebp + 16] ; len + sub edx, ecx + dec edx + add eax, edx + jmp .done + +.notfound: + mov eax, 0 + jmp .done +.done: + leave + ret + +; section .text +; global main +; main: +; push ebp +; mov ebp, esp + +; push message.size +; push message +; push buffer +; call amemcpy +; add esp, 12 + +; leave +; ret + +; section .data + +; message db "hello world!!!", 10, 0 +; message.size equ ($-message) + +; section .bss + +; buffer resb message.size + diff --git a/x86_assembly/analysis/bcd.asm b/x86_assembly/analysis/bcd.asm new file mode 100644 index 0000000..d81bf0e --- /dev/null +++ b/x86_assembly/analysis/bcd.asm @@ -0,0 +1,23 @@ +section .data + + value1 dd 0x12345945 + value2 dd 0x03234098 + value3 dd 0 + +; 9,111,847 + +section .text +global main +main: + clc + mov ecx, 4 + xor edi, edi +loop1: + mov al, [value1 + edi] + sbb al, [value2 + edi] + das + mov [value3, + edi], al + inc edi + loop loop1 + + ret \ No newline at end of file diff --git a/x86_assembly/analysis/call.c b/x86_assembly/analysis/call.c new file mode 100644 index 0000000..fae69c2 --- /dev/null +++ b/x86_assembly/analysis/call.c @@ -0,0 +1,14 @@ + +#include + +extern int add(int a, int b); +extern int __attribute__((fastcall)) sub(int a, int b); + +int main() +{ + int i = 5; + int j = 10; + // int k = add(i, j); + int k = sub(i, j); + printf("%d - %d = %d\n", i, j, k); +} diff --git a/x86_assembly/analysis/compile.c b/x86_assembly/analysis/compile.c new file mode 100644 index 0000000..e05e76f --- /dev/null +++ b/x86_assembly/analysis/compile.c @@ -0,0 +1,28 @@ +# 0 "compile.cc" +# 1 "/home/steven/source/github/computer/x86_assembly/analysis//" +# 0 "" +# 0 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 0 "" 2 +# 1 "compile.cc" +# 1 "compile.h" 1 + +void function(); +# 2 "compile.cc" 2 + +void function() +{ +} + +int main(int argc, char const *argv[]) +{ + function(); + + asm volatile( + "movl $1, %eax\n" + "movl $0, %ebx\n" + "int $0x80\n" + ); + + return 0; +} diff --git a/x86_assembly/analysis/compile.cc b/x86_assembly/analysis/compile.cc new file mode 100644 index 0000000..ccce9ed --- /dev/null +++ b/x86_assembly/analysis/compile.cc @@ -0,0 +1,18 @@ +#include "compile.h" + +void function() +{ +} + +int main(int argc, char const *argv[]) +{ + function(); + + asm volatile( + "movl $1, %eax\n" + "movl $0, %ebx\n" + "int $0x80\n" + ); + + return 0; +} diff --git a/x86_assembly/analysis/compile.h b/x86_assembly/analysis/compile.h new file mode 100644 index 0000000..bc9ebd5 --- /dev/null +++ b/x86_assembly/analysis/compile.h @@ -0,0 +1,2 @@ + +void function(); diff --git a/x86_assembly/analysis/compile.s b/x86_assembly/analysis/compile.s new file mode 100644 index 0000000..f7c1212 --- /dev/null +++ b/x86_assembly/analysis/compile.s @@ -0,0 +1,25 @@ + .file "compile.c" + .text + .globl function + .type function, @function +function: + nop + ret + .size function, .-function + .globl main + .type main, @function +main: + call function +#APP +# 11 "compile.cc" 1 + movl $1, %eax +movl $0, %ebx +int $0x80 + +# 0 "" 2 +#NO_APP + movl $0, %eax + ret + .size main, .-main + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits diff --git a/x86_assembly/analysis/control.c b/x86_assembly/analysis/control.c new file mode 100644 index 0000000..7d1c7b9 --- /dev/null +++ b/x86_assembly/analysis/control.c @@ -0,0 +1,48 @@ + +int compare(int condition, int a, int b) +{ + for (int i = 0; i < 10; i++) + { + if (condition) + continue; + else + break; + } +} + +int main() +{ + compare(1, 2, 3); + return 0; +} + +void test() +{ + int a = 1; + int b = 2; + int c = 3; + if (a == 3) + { + b++; + if (b == 5) + { + a++; + if (c == 6) + { + c++; + } + goto label; + } + else if (b == 6) + { + a++; + } + } + else + { + a++; + } + +label: + a++; +} diff --git a/x86_assembly/analysis/control.s b/x86_assembly/analysis/control.s new file mode 100644 index 0000000..61254f0 --- /dev/null +++ b/x86_assembly/analysis/control.s @@ -0,0 +1,77 @@ + .file "control.c" + .text + .globl compare + .type compare, @function +compare: + pushl %ebp + movl %esp, %ebp + subl $4, %esp + movl $0, -4(%ebp) + jmp .L2 +.L6: + cmpl $0, 8(%ebp) + je .L7 + nop + addl $1, -4(%ebp) +.L2: + cmpl $9, -4(%ebp) + jle .L6 + jmp .L5 +.L7: + nop +.L5: + nop + leave + ret + .size compare, .-compare + .globl main + .type main, @function +main: + pushl %ebp + movl %esp, %ebp + pushl $3 + pushl $2 + pushl $1 + call compare + addl $12, %esp + movl $0, %eax + leave + ret + .size main, .-main + .globl test + .type test, @function +test: + pushl %ebp + movl %esp, %ebp + subl $12, %esp + movl $1, -4(%ebp) + movl $2, -8(%ebp) + movl $3, -12(%ebp) + cmpl $3, -4(%ebp) + jne .L11 + addl $1, -8(%ebp) + cmpl $5, -8(%ebp) + jne .L12 + addl $1, -4(%ebp) + cmpl $6, -12(%ebp) + jne .L15 + addl $1, -12(%ebp) + jmp .L15 +.L12: + cmpl $6, -8(%ebp) + jne .L14 + addl $1, -4(%ebp) + jmp .L14 +.L11: + addl $1, -4(%ebp) + jmp .L14 +.L15: + nop +.L14: + addl $1, -4(%ebp) + nop + leave + ret + .size test, .-test + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits diff --git a/x86_assembly/analysis/cstring.c b/x86_assembly/analysis/cstring.c new file mode 100644 index 0000000..80590e9 --- /dev/null +++ b/x86_assembly/analysis/cstring.c @@ -0,0 +1,46 @@ + +#include +#include + +#define NULL 0 + +typedef unsigned int size_t; + +void *amemcpy(void *dest, const void *src, size_t count); + +void *memcpy(void *dest, const void *src, size_t count) +{ + char *dptr = dest; + const char *sptr = src; + for (size_t i = 0; i < count; i++) + { + dptr[i] = sptr[i]; + } + return dest; +} + +char message[] = "hello world!!!\n"; +char buffer[sizeof(message)]; + +int main(int argc, char const *argv[]) +{ + printf("%d\n", time(NULL)); + int total = 100000000; + int count = total; + while (count--) + { + memcpy(buffer, message, sizeof(message)); + } + + printf("%d\n", time(NULL)); + + count = total; + while (count--) + { + amemcpy(buffer, message, sizeof(message)); + } + + printf("%d\n", time(NULL)); + + return 0; +} diff --git a/x86_assembly/analysis/cstring.s b/x86_assembly/analysis/cstring.s new file mode 100644 index 0000000..8ed47c4 --- /dev/null +++ b/x86_assembly/analysis/cstring.s @@ -0,0 +1,111 @@ + .file "cstring.c" + .text + .globl memcpy + .type memcpy, @function +memcpy: + subl $12, %esp + movl 16(%esp), %eax + movl %eax, 4(%esp) + movl 20(%esp), %eax + movl %eax, (%esp) + movl $0, 8(%esp) + jmp .L2 +.L3: + movl (%esp), %edx + movl 8(%esp), %eax + addl %edx, %eax + movl 4(%esp), %ecx + movl 8(%esp), %edx + addl %ecx, %edx + movzbl (%eax), %eax + movb %al, (%edx) + addl $1, 8(%esp) +.L2: + movl 8(%esp), %eax + cmpl 24(%esp), %eax + jb .L3 + movl 16(%esp), %eax + addl $12, %esp + ret + + .size memcpy, .-memcpy + .globl message + .data + .align 4 + .type message, @object + .size message, 16 +message: + .string "hello world!!!\n" + .globl buffer + .bss + .align 4 + .type buffer, @object + .size buffer, 16 +buffer: + .zero 16 + .section .rodata +.LC0: + .string "%d\n" + .text + .globl main + .type main, @function +main: + subl $8, %esp + pushl $0 + call time + addl $4, %esp + pushl %eax + pushl $.LC0 + call printf + addl $8, %esp + movl $100000000, (%esp) + movl (%esp), %eax + movl %eax, 4(%esp) + jmp .L6 +.L7: + pushl $16 + pushl $message + pushl $buffer + call memcpy + addl $12, %esp +.L6: + movl 4(%esp), %eax + leal -1(%eax), %edx + movl %edx, 4(%esp) + testl %eax, %eax + jne .L7 + pushl $0 + call time + addl $4, %esp + pushl %eax + pushl $.LC0 + call printf + addl $8, %esp + movl (%esp), %eax + movl %eax, 4(%esp) + jmp .L8 +.L9: + pushl $16 + pushl $message + pushl $buffer + call amemcpy + addl $12, %esp +.L8: + movl 4(%esp), %eax + leal -1(%eax), %edx + movl %edx, 4(%esp) + testl %eax, %eax + jne .L9 + pushl $0 + call time + addl $4, %esp + pushl %eax + pushl $.LC0 + call printf + addl $8, %esp + movl $0, %eax + addl $8, %esp + ret + .size main, .-main + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits diff --git a/x86_assembly/analysis/dowhile.c b/x86_assembly/analysis/dowhile.c new file mode 100644 index 0000000..88fbf32 --- /dev/null +++ b/x86_assembly/analysis/dowhile.c @@ -0,0 +1,10 @@ + +int main() +{ + int sum = 0; + int count = 10; + do + { + sum += count; + } while (count--); +} \ No newline at end of file diff --git a/x86_assembly/analysis/dowhile.s b/x86_assembly/analysis/dowhile.s new file mode 100644 index 0000000..f1af301 --- /dev/null +++ b/x86_assembly/analysis/dowhile.s @@ -0,0 +1,24 @@ + .file "dowhile.c" + .text + .globl main + .type main, @function +main: + pushl %ebp + movl %esp, %ebp + subl $8, %esp + movl $0, -4(%ebp) + movl $10, -8(%ebp) +.L2: + movl -8(%ebp), %eax + addl %eax, -4(%ebp) + movl -8(%ebp), %eax + leal -1(%eax), %edx + movl %edx, -8(%ebp) + testl %eax, %eax + jne .L2 + movl $0, %eax + leave + ret + .size main, .-main + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits diff --git a/x86_assembly/analysis/float.asm b/x86_assembly/analysis/float.asm new file mode 100644 index 0000000..ac880f2 --- /dev/null +++ b/x86_assembly/analysis/float.asm @@ -0,0 +1,21 @@ +[bits 32] + +number dd 0.5; + +; 0x3f000000 +; 0b_0_0111_1110_000_0000_.. + +; 126 = -1 +; 1.000000 23 尾数 + +; 0.1 + +number2 dd 0.75 + +; 0.11 + +; 1.1 * 2 ^{0111_1110} + +; 0b_0_0111_1110_100_0000_.. +; 0b_0011_1111_0100_0000 +; 0x 3 f 4 0 diff --git a/x86_assembly/analysis/float2.asm b/x86_assembly/analysis/float2.asm new file mode 100644 index 0000000..3476597 --- /dev/null +++ b/x86_assembly/analysis/float2.asm @@ -0,0 +1,49 @@ +[bits 32] + +section .data + +value: + dd 0; 0 + dd 43.65; 1 + dd 22; + dd 76.34 + dd 3.1 + dd 12.43; 5 + dd 6; + dd 140.2; + dd 94.21; 8 +output: + db "result = %f", 10, 0 + +extern printf + +section .text +global main +main: + finit ; 初始化浮点控制寄存器 + + fld dword [value + 4 * 1]; 加载一个浮点数 + fidiv dword [value + 4 * 2]; 除一个整数 + + fld dword [value + 4 * 3] + fld dword [value + 4 * 4] + fmul st0, st1 + fadd st0, st2 + + fld dword [value + 4 * 5] + fimul dword [value + 4 * 6] + + fld dword [value + 4 * 7] + fld dword [value + 4 * 8] + fdivp + + fsubr st0, st1 + fdivr st0, st2 + + sub esp, 8 + fstp qword [esp] + push output + call printf + add esp, 12 + + ret diff --git a/x86_assembly/analysis/float_advance.asm b/x86_assembly/analysis/float_advance.asm new file mode 100644 index 0000000..89c38ba --- /dev/null +++ b/x86_assembly/analysis/float_advance.asm @@ -0,0 +1,66 @@ +section .data + + value1 dd 3.49 + value2 dd 4.0 + value3 dd 0.5 + + value4 dd 19.8 + value5 dd 3.4 + + +section .text +global main +main: + finit + + ; fld1 + ; fldl2t + ; fldl2e + ; fldpi + ; fldlg2 + ; fldln2 + ; fldz + + ; fldpi + ; frndint + + ; fldpi + ; fchs ; change sign + ; frndint + + ; fld dword [value1] + ; frndint ; 四舍五入 + + ; fabs ; + + ; fld dword [value2] + ; fsqrt ; square root + + ; fldpi + ; fsin + + ; fldpi + ; fcos + + ; fldpi + ; fsincos + + ; fldpi + ; fptan + + ; fld1 + ; fld1 + ; fpatan + + ; fld dword [value3] + ; f2xm1 + + fld dword [value5] + fld dword [value4] + fprem + + fld dword [value5] + fld dword [value4] + fprem1 + + ret \ No newline at end of file diff --git a/x86_assembly/analysis/float_branch.asm b/x86_assembly/analysis/float_branch.asm new file mode 100644 index 0000000..47f6539 --- /dev/null +++ b/x86_assembly/analysis/float_branch.asm @@ -0,0 +1,59 @@ +section .data + + value1 dd 3.49 + value2 dd 4.0 + +message: + db "%f %s %f", 10, 0 +sg: + db ">", 0 +sl: + db "<=", 0 + +extern printf + +section .text +global main +main: + finit + + fld dword [value1] + fld dword [value2] + + ; 0x3000 + ; 0x3100 + + ; 0b_0_0_11_0000 + ; 0b_0_0_11_0001 + + ; fcom + ; fstsw ax + ; sahf; 将 ah 寄存器中的值传送到 flag + + fcomi + + jc .greater +.less: + sub esp, 8 + fstp qword [esp] + push sl + sub esp, 8 + fstp qword [esp] + push message + call printf + ; printf(message, st1, <= , st0); + add esp, 24 + jmp .done +.greater: + sub esp, 8 + fstp qword [esp] + push sg + sub esp, 8 + fstp qword [esp] + push message + call printf + ; printf(message, st1, > , st0); + add esp, 24 + +.done: + ret \ No newline at end of file diff --git a/x86_assembly/analysis/for.c b/x86_assembly/analysis/for.c new file mode 100644 index 0000000..dbc63ff --- /dev/null +++ b/x86_assembly/analysis/for.c @@ -0,0 +1,9 @@ + +int main() +{ + int sum = 0; + for (int i = 1; i < 10; i++) + { + sum += i; + } +} \ No newline at end of file diff --git a/x86_assembly/analysis/for.s b/x86_assembly/analysis/for.s new file mode 100644 index 0000000..e12923b --- /dev/null +++ b/x86_assembly/analysis/for.s @@ -0,0 +1,30 @@ + .file "for.c" + .text + .globl main + .type main, @function + +main: + pushl %ebp + movl %esp, %ebp # 保存栈顶指针 + + subl $8, %esp # 预留局部变量空间 + + movl $0, -4(%ebp) # int sum = 0; + movl $1, -8(%ebp) # int i = 1; + + jmp .L2 +.L3: + movl -8(%ebp), %eax # eax = i + addl %eax, -4(%ebp) # sum += eax + addl $1, -8(%ebp) # i += 1 +.L2: + cmpl $9, -8(%ebp) # 9 - i + jle .L3 + + # 设置返回值,恢复栈顶,返回 + movl $0, %eax + leave + ret + .size main, .-main + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits diff --git a/x86_assembly/analysis/hello.c b/x86_assembly/analysis/hello.c new file mode 100644 index 0000000..97dcc63 --- /dev/null +++ b/x86_assembly/analysis/hello.c @@ -0,0 +1,6 @@ +#include + +int main() +{ + printf("hello world!!!\n"); +} diff --git a/x86_assembly/analysis/hello.s b/x86_assembly/analysis/hello.s new file mode 100644 index 0000000..781702d --- /dev/null +++ b/x86_assembly/analysis/hello.s @@ -0,0 +1,27 @@ + .file "hello.c" +# GNU C17 (GCC) version 11.1.0 (x86_64-pc-linux-gnu) +# compiled by GNU C version 11.1.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP + +# GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +# options passed: -m32 -mpreferred-stack-boundary=2 -mtune=generic -march=x86-64 -O0 -fno-asynchronous-unwind-tables -fno-pic -fno-stack-protector -fno-builtin + .text + .section .rodata +.LC0: + .string "hello world!!!\n" + .text + .globl main + .type main, @function +main: + pushl %ebp # + movl %esp, %ebp #, +# hello.c:5: printf("hello world!!!\n"); + pushl $.LC0 # + call printf # + addl $4, %esp #, + movl $0, %eax #, _3 +# hello.c:6: } + leave + ret + .size main, .-main + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits diff --git a/x86_assembly/analysis/if.c b/x86_assembly/analysis/if.c new file mode 100644 index 0000000..f20ddda --- /dev/null +++ b/x86_assembly/analysis/if.c @@ -0,0 +1,14 @@ + +int compare(int condition, int a, int b) +{ + if (condition) + return a; + else + return b; +} + +int main() +{ + compare(1, 2, 3); + return 0; +} diff --git a/x86_assembly/analysis/if.s b/x86_assembly/analysis/if.s new file mode 100644 index 0000000..53e44cd --- /dev/null +++ b/x86_assembly/analysis/if.s @@ -0,0 +1,45 @@ + .file "if.c" + .text + .globl compare + .type compare, @function + +compare: + pushl %ebp + movl %esp, %ebp + + # ebp ebp + # eip + # condition ebp + 8 + # a ebp + 12 + # b ebp + 16 + + cmpl $0, 8(%ebp) # condition + je .L2 + movl 12(%ebp), %eax # eax = a + jmp .L3 +.L2: + movl 16(%ebp), %eax # eax = b +.L3: + popl %ebp + ret + + .size compare, .-compare + .globl main + .type main, @function + +main: + pushl %ebp + movl %esp, %ebp + + pushl $3 + pushl $2 + pushl $1 + call compare + addl $12, %esp + + movl $0, %eax + leave + ret + .size main, .-main + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits diff --git a/x86_assembly/analysis/integer.asm b/x86_assembly/analysis/integer.asm new file mode 100644 index 0000000..26e9ae6 --- /dev/null +++ b/x86_assembly/analysis/integer.asm @@ -0,0 +1,25 @@ +[bits 32] + +section .text +global main +main: + ; mov al, 1 + + ; mov ebx, al + ; mov ebx, 0 + ; xor ebx, ebx + ; mov bl, al + + ; movzx ebx, al + + ; mov al, -1; 0xff + + ; movsx ebx, al; 0xffffffff + + ; mov al, 0xff; -1 + ; add al, 1; 0 + + mov al, 127; + inc al + + ret \ No newline at end of file diff --git a/x86_assembly/analysis/macro.asm b/x86_assembly/analysis/macro.asm new file mode 100644 index 0000000..1a15a85 --- /dev/null +++ b/x86_assembly/analysis/macro.asm @@ -0,0 +1,32 @@ +; %include "macro.inc" + +; %define square(x) (x * x) +; %define add(x, y) (x + y) + +; base +; limit +; type +; segment +; dpl +; present +; long_mode +; big +; granularity + +%macro descriptor 9 + dw %2 & 0xffff + dw %1 & 0xffff + db (%1 >> 16) & 0xff + db %3 | (%4 << 4) | (%5 << 6) | (%6 << 7) + db ((%2 >> 16) & 0xf) | (%7 << 5) | (%8 << 6) | (%9 << 7) + db (%1 >> 24) & 0xff +%endmacro + +descriptor 0x10000, 0xfff, 0b0010, 1, 0, 1, 0, 1, 0 + +; section .text +; global main +; main: +; mov eax, square(10) +; mov ebx, add(5, 3) +; ret diff --git a/x86_assembly/analysis/macro.inc b/x86_assembly/analysis/macro.inc new file mode 100644 index 0000000..0b6304b --- /dev/null +++ b/x86_assembly/analysis/macro.inc @@ -0,0 +1,6 @@ +%ifndef MACRO_INC +%define MACRO_INC + +extern printf + +%endif diff --git a/x86_assembly/analysis/makefile b/x86_assembly/analysis/makefile new file mode 100644 index 0000000..dd77210 --- /dev/null +++ b/x86_assembly/analysis/makefile @@ -0,0 +1,63 @@ + +CFLAGS:= -m32 \ + -O0 \ + -static \ + -fno-asynchronous-unwind-tables \ + -fno-pic \ + -mpreferred-stack-boundary=2 \ + -fno-stack-protector \ + -fno-builtin \ + -fomit-frame-pointer \ + # -fverbose-asm \ + +CC:=gcc + +.PHONY: hello.s +hello.s: hello.c + gcc $(CFLAGS) -S $< -o $@ + + +.PHONY: variable.s +variable.s: variable.c + gcc $(CFLAGS) -S $< -o $@ + + +.PHONY: test.s +test.s: test.c + gcc $(CFLAGS) -S $< -o $@ + +%.s: %.c + gcc $(CFLAGS) -S $< -o $@ + +DEBUG:=-g + +%.o: %.asm + nasm -f elf32 $(DEBUG) $< -o $@ + +%.o: %.c + gcc $(CFLAGS) $(DEBUG) -c $< -o $@ + +%.c: %.cc + gcc $(CFLAGS) $(DEBUG) -E $< -o $@ + +# %.o: %.s +# as -32 $< -o $@ + +%.bin: %.asm + nasm $(DEBUG) $< -o $@ + +%.out: %.o + # ld -m elf_i386 -static $< -o $@ -e main + gcc $(CFLAGS) $(DEBUG) $< -o $@ + +call.out: call.o subcall.o + gcc $(CFLAGS) $(DEBUG) $^ -o $@ + +cstring.out: cstring.o astring.o + gcc $(CFLAGS) $(DEBUG) $^ -o $@ + +.PHONY:clean +clean: + rm -rf *.o + rm -rf *.out + rm -rf *.bin diff --git a/x86_assembly/analysis/structure.c b/x86_assembly/analysis/structure.c new file mode 100644 index 0000000..cb81507 --- /dev/null +++ b/x86_assembly/analysis/structure.c @@ -0,0 +1,32 @@ + +// typedef struct struct_t +// { +// char c1; +// int i1; +// char c2; +// int i2; +// char c3; +// int i3; +// } struct_t; + +// typedef struct struct_t +// { +// int i1; +// int i2; +// int i3; + +// char c1; +// char c2; +// char c3; +// } struct_t; + +// struct_t data; + +typedef enum enum_t +{ + ENUM1 = 1, + ENUM2, + ENUM3 +} enum_t; + +enum_t edata = 345; \ No newline at end of file diff --git a/x86_assembly/analysis/structure.s b/x86_assembly/analysis/structure.s new file mode 100644 index 0000000..f33e548 --- /dev/null +++ b/x86_assembly/analysis/structure.s @@ -0,0 +1,11 @@ + .file "structure.c" + .text + .globl edata + .data + .align 4 + .type edata, @object + .size edata, 4 +edata: + .long 345 + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits diff --git a/x86_assembly/analysis/subcall.asm b/x86_assembly/analysis/subcall.asm new file mode 100644 index 0000000..0fe1f70 --- /dev/null +++ b/x86_assembly/analysis/subcall.asm @@ -0,0 +1,39 @@ +[bits 32] + +extern printf + +section .text +global add +add: + push ebp + mov ebp, esp + + push message + call printf + add esp, 4 + + ; ebp ; ebp + 0 + ; eip ; ebp + 4 + ; a ; ebp + 8 + ; b ; ebp + 12 + + mov eax, [ebp + 8]; eax = a + add eax, [ebp + 12]; b + + leave + ret + +global sub +sub: + push ebp + mov ebp, esp + + mov eax, ecx + sub eax, edx + + leave + ret + +section .data + + message db "add called!!!", 10, 0 diff --git a/x86_assembly/analysis/variable.c b/x86_assembly/analysis/variable.c new file mode 100644 index 0000000..a126565 --- /dev/null +++ b/x86_assembly/analysis/variable.c @@ -0,0 +1,16 @@ + +#include + +int add(int a, int b) +{ + int c = a + b; + return c; +} + +int main() +{ + int i = 5; + int j = 10; + int k = add(i, j); + printf("%d + %d = %d\n", i, j, k); +} diff --git a/x86_assembly/analysis/variable.s b/x86_assembly/analysis/variable.s new file mode 100644 index 0000000..17f5193 --- /dev/null +++ b/x86_assembly/analysis/variable.s @@ -0,0 +1,62 @@ + .file "variable.c" + .text + .globl add + .type add, @function +add: + pushl %ebp + movl %esp, %ebp # 保存栈顶指针 + + subl $4, %esp # 预留栈空间 int c; + + movl 8(%ebp), %edx # a + movl 12(%ebp), %eax # b + + addl %edx, %eax # 执行加法 + + movl %eax, -4(%ebp) # 给 c 赋值 + + movl -4(%ebp), %eax # 函数的返回值存储在 eax 寄存器中 + + leave # 恢复栈顶指针和返回 + ret + + .size add, .-add + .section .rodata +.LC0: + .string "%d + %d = %d\n" + .text + .globl main + .type main, @function +main: + pushl %ebp + movl %esp, %ebp # 保存栈顶指针 + + subl $12, %esp # 为局部变量留栈内存空间 + + movl $5, -4(%ebp) # int i = 5; + movl $10, -8(%ebp) # int j = 10; + + pushl -8(%ebp) # push j + pushl -4(%ebp) # push i + + call add # 调用 + + addl $8, %esp # 恢复栈 + + movl %eax, -12(%ebp) # int k = add(i, j); + pushl -12(%ebp) # k + pushl -8(%ebp) # j + pushl -4(%ebp) # i + pushl $.LC0 # "%d + %d = %d\n + + call printf # 调用 + + addl $16, %esp # 恢复栈 + + movl $0, %eax # 函数返回值 + + leave # 恢复栈顶指针 + ret # 函数返回 + .size main, .-main + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits diff --git a/x86_assembly/analysis/while.c b/x86_assembly/analysis/while.c new file mode 100644 index 0000000..a60f8b3 --- /dev/null +++ b/x86_assembly/analysis/while.c @@ -0,0 +1,10 @@ + +int main() +{ + int sum = 0; + int count = 10; + while (count --) + { + sum += count; + } +} \ No newline at end of file diff --git a/x86_assembly/bochs/PKGBUILD b/x86_assembly/bochs/PKGBUILD new file mode 100644 index 0000000..02c953b --- /dev/null +++ b/x86_assembly/bochs/PKGBUILD @@ -0,0 +1,61 @@ +# Maintainer: Kyle Keen +# Contributor: Tom Newsom +# Contributor: Kevin Piche + +pkgname=bochs +pkgver=2.6.11 +pkgrel=1 +pkgdesc="A portable x86 PC emulation software package, including GUI debugger" +arch=('x86_64') +url="http://bochs.sourceforge.net/" +license=('LGPL') +depends=('gcc-libs' 'libxrandr' 'libxpm' 'gtk2') +source=("https://downloads.sourceforge.net/sourceforge/$pkgname/$pkgname-$pkgver.tar.gz" + "fix-build.patch") +sha256sums=('63897b41fbbbdfb1c492d3c4dee1edb4224282a07bbdf442a4a68c19bcc18862' + 'SKIP') + +prepare() { + cd "$srcdir/$pkgname-$pkgver" + # 4.X kernel is basically 3.20 + sed -i 's/2\.6\*|3\.\*)/2.6*|3.*|4.*)/' configure* + + patch -p1 < ../fix-build.patch # https://sourceforge.net/p/bochs/bugs/1411/ +} + +build() { + cd "$srcdir/$pkgname-$pkgver" + + ./configure \ + --prefix=/usr \ + --without-wx \ + --with-x11 \ + --with-x \ + --with-term \ + --disable-docbook \ + --enable-cpu-level=6 \ + --enable-fpu \ + --enable-3dnow \ + --enable-disasm \ + --enable-smp \ + --enable-x86-64 \ + --enable-avx \ + --enable-evex \ + --enable-long-phy-address \ + --enable-disasm \ + --enable-pcidev \ + --enable-usb \ + --enable-debugger \ + --with-sdl \ + --enable-x86-debugger \ + --enable-all-optimizations \ + --enable-plugins + sed -i 's/^LIBS = /LIBS = -lpthread/g' Makefile + make -j 1 +} + +package() { + cd "$srcdir/$pkgname-$pkgver" + make DESTDIR="$pkgdir" install + install -Dm644 .bochsrc "$pkgdir/etc/bochsrc-sample.txt" +} \ No newline at end of file diff --git a/x86_assembly/bochs/fix-build.patch b/x86_assembly/bochs/fix-build.patch new file mode 100644 index 0000000..034c759 --- /dev/null +++ b/x86_assembly/bochs/fix-build.patch @@ -0,0 +1,33 @@ +Description: Fix the build with SMP enabled +Origin: https://sourceforge.net/p/bochs/code/13778/ + +Index: bochs/bx_debug/dbg_main.cc +=================================================================== +--- bochs/bx_debug/dbg_main.cc (revision 13777) ++++ bochs/bx_debug/dbg_main.cc (working copy) +@@ -1494,11 +1494,11 @@ + { + char cpu_param_name[16]; + +- Bit32u index = BX_ITLB_INDEX_OF(laddr); ++ Bit32u index = BX_CPU(dbg_cpu)->ITLB.get_index_of(laddr); + sprintf(cpu_param_name, "ITLB.entry%d", index); + bx_dbg_show_param_command(cpu_param_name, 0); + +- index = BX_DTLB_INDEX_OF(laddr, 0); ++ index = BX_CPU(dbg_cpu)->DTLB.get_index_of(laddr); + sprintf(cpu_param_name, "DTLB.entry%d", index); + bx_dbg_show_param_command(cpu_param_name, 0); + } + +Index: bochs/gui/gtk_enh_dbg_osdep.cc +=================================================================== +--- bochs/gui/gtk_enh_dbg_osdep.cc ++++ bochs/gui/gtk_enh_dbg_osdep.cc +@@ -819,7 +819,7 @@ void ShowDListCols (int totcols) + while (++i < firsthide) + gtk_tree_view_column_set_visible(AllCols[i], TRUE); + while (i < 23) +- gtk_tree_view_column_set_visible(AllCols[i], FALSE); ++ gtk_tree_view_column_set_visible(AllCols[i++], FALSE); + } diff --git a/x86_assembly/build/bochsrc b/x86_assembly/build/bochsrc new file mode 100644 index 0000000..7b9b020 --- /dev/null +++ b/x86_assembly/build/bochsrc @@ -0,0 +1,57 @@ +# configuration file generated by Bochs +plugin_ctrl: unmapped=true, biosdev=true, speaker=true, extfpuirq=true, parallel=true, serial=true, iodebug=true +config_interface: textconfig +display_library: x, options="gui_debug" +memory: host=32, guest=32 +romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x00000000, options=none +vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest" +boot: disk +floppy_bootsig_check: disabled=0 +# no floppya +# no floppyb +ata0: enabled=true, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 +ata0-master: type=disk, path="master.img", mode=flat +ata0-slave: type=none +ata1: enabled=true, ioaddr1=0x170, ioaddr2=0x370, irq=15 +ata1-master: type=none +ata1-slave: type=none +ata2: enabled=false +ata3: enabled=false +optromimage1: file=none +optromimage2: file=none +optromimage3: file=none +optromimage4: file=none +optramimage1: file=none +optramimage2: file=none +optramimage3: file=none +optramimage4: file=none +pci: enabled=1, chipset=i440fx +vga: extension=vbe, update_freq=5, realtime=1 +cpu: count=1:1:1, ips=4000000, quantum=16, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0 +cpuid: level=6, stepping=3, model=3, family=6, vendor_string="AuthenticAMD", brand_string="AMD Athlon(tm) processor" +cpuid: mmx=true, apic=xapic, simd=sse2, sse4a=false, misaligned_sse=false, sep=true +cpuid: movbe=false, adx=false, aes=false, sha=false, xsave=false, xsaveopt=false, avx_f16c=false +cpuid: avx_fma=false, bmi=0, xop=false, fma4=false, tbm=false, x86_64=true, 1g_pages=false +cpuid: pcid=false, fsgsbase=false, smep=false, smap=false, mwait=true +print_timestamps: enabled=0 +debugger_log: - +magic_break: enabled=1 +port_e9_hack: enabled=0 +private_colormap: enabled=0 +clock: sync=none, time0=local, rtc_sync=0 +# no cmosimage +log: - +logprefix: %t%e%d +debug: action=ignore +info: action=report +error: action=report +panic: action=ask +keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none +mouse: type=ps2, enabled=false, toggle=ctrl+mbutton +speaker: enabled=true, mode=system +parport1: enabled=true, file=none +parport2: enabled=false +com1: enabled=true, mode=null +com2: enabled=false +com3: enabled=false +com4: enabled=false diff --git "a/x86_assembly/docs/15 \347\241\254\347\233\230\350\257\273\345\206\231.md" "b/x86_assembly/docs/15 \347\241\254\347\233\230\350\257\273\345\206\231.md" new file mode 100644 index 0000000..8ec9009 --- /dev/null +++ "b/x86_assembly/docs/15 \347\241\254\347\233\230\350\257\273\345\206\231.md" @@ -0,0 +1,61 @@ +# 硬盘读写 + +## PC 的状态 + +1. 加电 +2. BIOS +3. 主引导扇区 --> 0x7c00 +4. 跳转到 --> 0x7c00 + +--- + +- 主引导扇区只有 512 个字节 / 包括硬盘分区信息 + +--- + +- IDE Integrated Drive Electronics +- ATA Advanced Technology Attachment +- PATA +- SATA +- NVME + +--- + +- CHS 模式 (Cylinder / Head / Sector) +- LBA 模式 Logical Block Address + +--- + +| Primary 通道 | Secondary 通道 | in 操作 | out 操作 | +| ----------------------- | -------------- | ------------ | ------------ | +| Command Block Registers | +| 0x1F0 | 0x170 | Data | Data | +| 0x1F1 | 0x171 | Error | Features | +| 0x1F2 | 0x172 | Sector count | Sector count | +| 0x1F3 | 0x173 | LBA low | LBA low | +| 0x1F4 | 0x174 | LBA mid | LBA mid | +| 0x1F5 | 0x175 | LBA high | LBA high | +| 0x1F6 | 0x176 | Device | Device | +| 0x1F7 | 0x177 | Status | Command | + +--- + +- 0x1F0 / 16bit 读写数据 +- 0x1F1 +- 0x1F2 / 扇区数量 +- 0x1F3 - 0x1F5 / 起始扇区的前 24 位 0 ~ 23 位 +- 0x1F6 + - 0 - 3 / LBA 24 ~ 27 位 + - 4:0 主盘,1 从盘 + - 6:0 CHS 模式 , 1 LBA + - 5 7 : 固定为 1 +- 0x1F7: + out + - 0xEC:识别硬盘 + - 0x20:读硬盘 + - 0x30:写硬盘 + + in + - 0 ERR + - 3 DRQ 数据准备完毕 + - 7 BUSY 硬盘繁忙 diff --git "a/x86_assembly/docs/17 32 \344\275\215\346\236\266\346\236\204.md" "b/x86_assembly/docs/17 32 \344\275\215\346\236\266\346\236\204.md" new file mode 100644 index 0000000..8366566 --- /dev/null +++ "b/x86_assembly/docs/17 32 \344\275\215\346\236\266\346\236\204.md" @@ -0,0 +1,52 @@ +# 32 位架构 + +- 实模式 / 8086模式 +- 保护模式 / 32 保护模式 + +---- + +- 1982 / 80286 - 16/24 保护模式 +- 1984 / 80386 / 32 位的CPU +- 1989 / 80486 / 引入内存分页的机制 + +--- + +## 数据结构和算法 + +- IT Information Technology 信息技术 +- 数据 / 算法 +- 寄存器 - 内存 / 某一段程序 + +--- + +```mermaid +flowchart LR +输入数据 --> 程序 --> 输出数据 +``` + +## 寄存器 + +- A/B/C/DX /SP/BP/SI/DI +- EAX/EBX/ECX/EDX ... + +- IP / EIP +- FLAGS / EFLAGS + +- Extend + +- RAX/RBX.... + +--- + +- CS/DS/SS/ES +- FS/GS + +--- + +## 寻址方式 + +- BX/BP + SI/DI + 偏移地址 +- ERX + ERX * (1/2/4/8) + 偏移地址 + +--- + diff --git "a/x86_assembly/docs/18 \345\206\205\345\255\230\346\243\200\346\265\213.md" "b/x86_assembly/docs/18 \345\206\205\345\255\230\346\243\200\346\265\213.md" new file mode 100644 index 0000000..1f380ad --- /dev/null +++ "b/x86_assembly/docs/18 \345\206\205\345\255\230\346\243\200\346\265\213.md" @@ -0,0 +1,42 @@ +# 内存检测 + +BIOS 0x15 0xe820 + +Address Range Descriptor Structure ARDS + +| 字节偏移量 | 属性名称 | 描述 | +| ---------- | ------------ | -------------------------------- | +| 0 | BaseAddrLow | 基地址的低 32 位 | +| 4 | BaseAddrHigh | 基地址的高 32 位 | +| 8 | LengthLow | 内存长度的低 32 位,以字节为单位 | +| 12 | LengthHigh | 内存长度的高 32 位,以字节为单位 | +| 16 | Type | 本段内存的类型 | + +## Type 字段 + +| Type 值 | 名称 | 描述 | +| ------- | -------------------- | ------------------------------------------------------------------------------------ | +| 1 | AddressRangeMemory | 这段内存可以被操作系统使用 | +| 2 | AddressRangeReserved | 内存使用中或者被系统保留,操作系统不可以用此内存 | +| 其他 | 未定义 | 未定义,将来会用到.目前保留. 但是需要操作系统一样将其视为ARR(AddressRangeReserved) | + + +## 调用前输入 + +| 寄存器或状态位 | 参数用途 | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| EAX | 子功能号: EAX 寄存器用来指定子功能号,此处输入为 0xE820 | +| EBX | 内存信息需要按类型分多次返回,由于每次执行一次中断都只返回一种类型内存的ARDS 结构,所以要记录下一个待返回的内存ARDS,在下一次中断调用时通过此值告诉 BIOS 该返回哪个 ARDS,这就是后续值的作用。第一次调用时一定要置为0,EBX 具体值我们不用关注,字取决于具体 BIOS 的实现,每次中断返回后,BIOS 会更新此值 | +| ES: DI | ARDS 缓冲区:BIOS 将获取到的内存信息写入此寄存器指向的内存,每次都以 ARDS 格式返回 | +| ECX | ARDS 结构的字节大小:用来指示 BIOS 写入的字节数。调用者和 BIOS 都同时支持的大小是 20 字节,将来也许会扩展此结构 | +| EDX | 固定为签名标记 `0x534d4150`,此十六进制数字是字符串 `SMAP` 的ASCII 码: BIOS 将调用者正在请求的内存信息写入 ES: DI 寄存器所指向的ARDS 缓冲区后,再用此签名校验其中的信息 | + +## 返回值 + +| 寄存器或状态位 | 参数用途 | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| CF 位 | 若CF 位为 0 表示调用未出错,CF 为1,表示调用出错 | +| EAX | 字符串 SMAP 的 ASCII 码 `0x534d4150` | +| ES:DI | ARDS 缓冲区地址,同输入值是一样的,返回时此结构中己经被BIOS 填充了内存信息 | +| ECX | BIOS 写入到 ES:DI 所指向的 ARDS 结构中的字节数,BIOS 最小写入 20 字节 | +| EBX | 后续值:下一个 ARDS 的位置。每次中断返回后,BIOS 会更新此值, BIOS 通过此值可以找到下一个待返回的 ARDS 结构,咱们不需要改变 EBX 的值,下一次中断调用时还会用到它。在 CF 位为 0 的情况下,若返回后的 EBX 值为 0,表示这是最后一个 ARDS 结构 | \ No newline at end of file diff --git "a/x86_assembly/docs/19 \344\277\235\346\212\244\346\250\241\345\274\217\345\222\214\345\205\250\345\261\200\346\217\217\350\277\260\347\254\246.md" "b/x86_assembly/docs/19 \344\277\235\346\212\244\346\250\241\345\274\217\345\222\214\345\205\250\345\261\200\346\217\217\350\277\260\347\254\246.md" new file mode 100644 index 0000000..e6d32cc --- /dev/null +++ "b/x86_assembly/docs/19 \344\277\235\346\212\244\346\250\241\345\274\217\345\222\214\345\205\250\345\261\200\346\217\217\350\277\260\347\254\246.md" @@ -0,0 +1,117 @@ +# 保护模式和全局描述符 + +8086 1M +80286 保护模式 16 + +## 保护模式 + +- 信息 +- 寄存器 / 有一些寄存器只能被操作系统访问 +- 高速缓存 +- 内存 / 描述符 +- 外部设备 / 硬盘 / in/out + +## 全局描述符 + +- 内存的起始位置 +- 内存的长度 / 界限 = 长度 - 1 +- 内存属性 + +```cpp +typedef struct descriptor /* 共 8 个字节 */ +{ + unsigned short limit_low; // 段界限 0 ~ 15 位 + unsigned int base_low : 24; // 基地址 0 ~ 23 位 16M + unsigned char type : 4; // 段类型 + unsigned char segment : 1; // 1 表示代码段或数据段,0 表示系统段 + unsigned char DPL : 2; // Descriptor Privilege Level 描述符特权等级 0 ~ 3 + unsigned char present : 1; // 存在位,1 在内存中,0 在磁盘上 + unsigned char limit_high : 4; // 段界限 16 ~ 19; + unsigned char available : 1; // 该安排的都安排了,送给操作系统吧 + unsigned char long_mode : 1; // 64 位扩展标志 + unsigned char big : 1; // 32 位 还是 16 位; + unsigned char granularity : 1; // 粒度 4KB 或 1B + unsigned char base_high; // 基地址 24 ~ 31 位 +} __attribute__((packed)) descriptor; +``` + +## type segment = 1 + +| E | C/D | R/W | A | + +- A: Accessed 是否被 CPU 访问过 +- E: 1/代码 0/数据 Executable +- E = 1:代码段 + - C: 是否是依从代码段 + - R: 是否可读 +- E = 1: 数据段 + - D: 0 向上扩展 / 1 向下扩展 + - W: 是否可写 + +## 全局描述符表 GDT Global Descriptor Table + +- 表 - 数组 - 顺序表 +- 链表 - 链表 +- 哈希表 + +```cpp +descriptor gdt[8192]; +``` + +- 0 必须全为 0 - NULL 描述符 +- 8191 描述符 + +---- + +- gdtr / 全局描述符表的起始位置和长度 + +```s +lgdt [gdt_ptr]; 加载 gdt +sgdt [gdt_ptr]; 保存 gdt +``` + +```cpp +typedef struct pointer +{ + unsigned short limit; // size - 1 + unsigned int base; +} __attribute__((packed)) pointer; +``` + +## 段选择子 + +- 只需要一个代码段 +- 需要一个或多个数据段 / 栈段 / 数据段 +- 加载到段寄存器中 / 校验特权级 + +```cpp +typedef struct selector +{ + unsigned char RPL : 2; + unsigned char TI : 1; + unsigned short index : 13; +} __attribute__((packed)) selector; +``` + +- cs / ds / es / ss +- fs / gs + +## A20 线 + +8086 1M + +段地址 * 16 + 偏移地址 > 1M + +80286 16M 24 根地址线 +386 32 地址线,4G + +地址回绕 + +0x92 端口 + +- +- + +## PE Protect Enable + +cr0 寄存器 0 位 置为 1 diff --git "a/x86_assembly/docs/21 \345\206\205\345\255\230\346\230\240\345\260\204.md" "b/x86_assembly/docs/21 \345\206\205\345\255\230\346\230\240\345\260\204.md" new file mode 100644 index 0000000..eaacbd1 --- /dev/null +++ "b/x86_assembly/docs/21 \345\206\205\345\255\230\346\230\240\345\260\204.md" @@ -0,0 +1,86 @@ +# 内存映射 486 + +虚拟内存映射 + +- 可以支持虚拟内存 / 使用硬盘来模拟内存 +- 可以支持多进程访问同一个内存地址 + +- 0x10000 - 0x10000 +- 0x10000 - 0x20000 + +线性地址 / 物理地址 + +## 内存分页 + +32位地址 4G 内存,4KB + +$$ +4G / 4K = 2^{32} / 2^{12} = 2^{20} +$$ + +```cpp +unsigned int page_table[1 << 20]; +``` + +4M / 4K = 1024 个页 + + +页目录 + +```cpp +unsigned int pde[1024]; +``` + +页表 + +8K + +## 页表的信息 + +```cpp +typedef struct page_entry +{ + unsigned char present : 1; // 1 是否在内存中 + unsigned char write : 1; // 0 只读 / 1 可写 + unsigned char user : 1; // 1 普通用户 // 0 超级用户,特权级 3 不允许访问 + unsigned char pwt : 1; // 1 页通写,表示该页需要高速缓存 + unsigned char pcd : 1; // 1 禁止高速缓存 + unsigned char accessed : 1; // 1 是否被 CPU + unsigned char dirty : 1; // 1 脏位 + unsigned char pat : 1; // 1 页属性 / 0 + unsigned char global : 1; // 1 全局位,应该放在快表中 + unsigned char avl : 3; // 该安排的都安排了,送给操作系统吧 + unsigned int index : 20; // 页索引 +} __attribute__((packed)) page_entry; +``` + +```cpp +unsigned int pde[1024]; 0x400 / 0x1000 +unsigned int pte[1024]; +``` + +0x0001_0000 + +0b0000_0000_00_00_0001_0000_0000_0000_0000 + +00_0001_0000 + +0b010 + +--- + +0xC001_0000 + +0b1100_0000_00_00_0001_0000_0000_0000_1000 + +11_00_00_00_00 = 0x300 + +--- + +0b1111_1111_11_00_0001_0000_0000_0000_1000 + +0xfffff000 + +0b1111_1111_11_00_0000_0000_0000_0000_1000 + +0xffc00000; diff --git "a/x86_assembly/docs/22 ELF \346\226\207\344\273\266\346\240\274\345\274\217\347\256\200\344\273\213.md" "b/x86_assembly/docs/22 ELF \346\226\207\344\273\266\346\240\274\345\274\217\347\256\200\344\273\213.md" new file mode 100644 index 0000000..8941481 --- /dev/null +++ "b/x86_assembly/docs/22 ELF \346\226\207\344\273\266\346\240\274\345\274\217\347\256\200\344\273\213.md" @@ -0,0 +1,28 @@ +# ELF 文件格式简介 + +Executable and Linking Format / 可执行和链接的格式 + +- 可执行程序 python / bash / gcc --> PE (.exe) +- 可重定位文件 / 静态库 / gcc -c `.o` --> .o.a / .lib +- 共享的目标文件 / 动态链接库 --> .so/.dll + +---- + +C 语言 --> 汇编 + +- 代码 .text +- 数据 + - .data / 已经初始化过的数据 + - .bss / 未初始化的数据 - buffer 缓存区域 + +--- + readelf -e file.o + +--- + objdump -d a.out + +PIE - Position Independent Executable + +Intel / AT&T + +gas GNU AT&T diff --git "a/x86_assembly/docs/23 AT&T \350\257\255\346\263\225\346\240\274\345\274\217.md" "b/x86_assembly/docs/23 AT&T \350\257\255\346\263\225\346\240\274\345\274\217.md" new file mode 100644 index 0000000..41da8de --- /dev/null +++ "b/x86_assembly/docs/23 AT&T \350\257\255\346\263\225\346\240\274\345\274\217.md" @@ -0,0 +1,85 @@ +# AT&T 语法格式 + +C --> 汇编 +gas 伪指令 + +--- + +> AT&T 默认数内存地址 + +## 立即数 + +立即数前面要加 `$` + + $123 # + 123 + + mov dword eax, message + movl $message, %eax + +# 寄存器 + +寄存器前要加上 `%` + + +## 数据传送指令 + + movx source, destination + +数据的传送方向是从左向右的。 + + movl %eax, %ebx + +等价于,Intel 语法: + + mov ebx, eax + +| movx | 描述 | Intel | +| ---- | ----- | --------- | +| movl | 32 位 | mov dword | +| movw | 16 位 | mov word | +| movb | 8 位 | mov byte | + +## 数据类型 + +| 命令 | 数据类型 | nasm | +| --------- | ----------------------- | ------ | +| `.ascii` | 字符串 | `db` | +| `.asciz` | 以 `\0` 结尾的字符串 | `db 0` | +| `.byte` | 字节 | `db` | +| `.double` | 双精度浮点 | `dq` | +| `.float` | 单精度浮点 | `dd` | +| `.int` | 32位整数 | `dd` | +| `.long` | 32位整数和(`.int` 相同) | `dd` | +| `.octa` | 16字节整数 | | +| `.quad` | 8字节整数 | `dq` | +| `.short` | 16位整数 | `dw` | +| `.single` | 单精度浮点 | `dd` | + +只针对汇编器,伪指令。 + +## 伪指令 + +节定义 `.section`;段,`segment = section + ... + section` + +代码段 `.text` 数据段 `.data` bss 段 `.bss` + +BSS Block Started Symbol; `resb` + +| 命令 | 描述 | +| -------- | --------------------------------- | +| `.comm` | 通用缓存区域 | +| `.lcomm` | 本地缓存区域 (只本文件可用的区域) | + +## 寻址方式 + +> [offset_address + index * size + base_address] ; 32 bit + +> base_address(offset_address, index, size) + +offset_address, index 必须是寄存器,size 1, 2, 4, 8 + +```s +movl %edx, 4(%edi, %eax, 8) # att 语法 +mov dword [edi + eax * 8 + 4] ; Intel 语法 +``` \ No newline at end of file diff --git "a/x86_assembly/docs/24 gcc \346\261\207\347\274\226\345\210\206\346\236\220.md" "b/x86_assembly/docs/24 gcc \346\261\207\347\274\226\345\210\206\346\236\220.md" new file mode 100644 index 0000000..604f2e4 --- /dev/null +++ "b/x86_assembly/docs/24 gcc \346\261\207\347\274\226\345\210\206\346\236\220.md" @@ -0,0 +1,60 @@ +# gcc 汇编分析 + + +## CFI + +Call Frame Information 调用栈帧信息 + +`.cfi_` 用于调试的信息,可以在调用失败的时候回溯栈。 + +A --> B --> C (异常) + + -fno-asynchronous-unwind-tables + + +## PIC + +Position Independent Code / 位置无关的代码 + +动态链接 + + mov eax, eip; + +上面这条指令是无效的。调用了 `__x86.get_pc_thunk.ax` 函数来获取 `eip` 的值。 + + -fno-pic + +## 栈对齐 + +-16 = 0 - 16 = 0x00000000 - 0x10 = 0xfffffff0 + +0b1{28}0000 + + andl $-16, %esp + +将栈对齐到 16 字节 + + -mpreferred-stack-boundary=2 + +## Intel + + -masm=intel + +## 代码 + +```s +main: + push ebp ; + mov ebp, esp ; 保存栈顶指针 + + push OFFSET FLAT:.LC0 ; 传递参数 + call puts ; 调用 + add esp, 4 ; 调用之后恢复栈 + + mov eax, 0; 返回值,存在 eax 寄存器中 + + leave + # mov esp, ebp + # pop ebp + ret +``` diff --git "a/x86_assembly/docs/25 \345\217\230\351\207\217\345\222\214\345\207\275\346\225\260\345\217\202\346\225\260.md" "b/x86_assembly/docs/25 \345\217\230\351\207\217\345\222\214\345\207\275\346\225\260\345\217\202\346\225\260.md" new file mode 100644 index 0000000..74552d9 --- /dev/null +++ "b/x86_assembly/docs/25 \345\217\230\351\207\217\345\222\214\345\207\275\346\225\260\345\217\202\346\225\260.md" @@ -0,0 +1,67 @@ +# x86 汇编语言 - 25 C 变量和函数参数 + +## 问题 + +- as 编译的问题 +- text 段重定位的警告 + +## 全局变量 + +## 局部变量 + +生命周期 - 两个大括号之间 + +局部变量存储在栈中 + +## 函数全局变量 + +```cpp +void fun1() +{ + static int a = 3; +} + +void fun2() +{ + static int a = 5; +} + +int main() +{ + static int a = 0; + int b = 5; + return 0; +} +``` + +## 栈保护 + +```cpp +#include + +int main() +{ + char str[5]; + strcpy(str, "hello world\n"); +} +``` + +## 参数传递 + +```cpp +#include + +int add(int a, int b) +{ + int c = a + b; + return c; +} + +int main() +{ + int i = 5; + int j = 10; + int k = add(i, j); + printf("%d + %d = %d\n", i, j, k); +} +``` diff --git "a/x86_assembly/docs/26 C \345\276\252\347\216\257\344\270\216\345\210\206\346\224\257.md" "b/x86_assembly/docs/26 C \345\276\252\347\216\257\344\270\216\345\210\206\346\224\257.md" new file mode 100644 index 0000000..4f3a680 --- /dev/null +++ "b/x86_assembly/docs/26 C \345\276\252\347\216\257\344\270\216\345\210\206\346\224\257.md" @@ -0,0 +1,79 @@ +# 26 C 循环与分支 + +## builtin + + + +## for 循环 + +```cpp +int main() +{ + int sum = 0; + for (int i = 1; i < 10; i++) + { + sum += i; + } +} +``` + +## while 循环 + +lea Load Effective Address,加载有效地址 + +```cpp +int main() +{ + int sum = 0; + int count = 10; + while (count --) + { + sum += count; + } +} +``` + +## if 分支 + +```cpp +int compare(int condition, int a, int b) +{ + if (condition) + return a; + else + return b; +} + +int main() +{ + compare(1, 2, 3); + return 0; +} +``` + +## switch 分支 + +## continue break + +```cpp +int compare(int condition, int a, int b) +{ + for (int i = 0; i < 10; i++) + { + if (condition) + continue; + else + break; + } +} + +int main() +{ + compare(1, 2, 3); + return 0; +} +``` + +## 忠告 + +> 尽可能不要嵌套分支 diff --git "a/x86_assembly/docs/27 C \347\273\223\346\236\204\344\275\223.md" "b/x86_assembly/docs/27 C \347\273\223\346\236\204\344\275\223.md" new file mode 100644 index 0000000..e907479 --- /dev/null +++ "b/x86_assembly/docs/27 C \347\273\223\346\236\204\344\275\223.md" @@ -0,0 +1,109 @@ +# C 结构体 + +## gcc 汇编标记 + +| 标记 | 英文 | 解释 | +| ---- | ------------------------ | ------------ | +| LC0 | local constant | 本地常量 | +| LFB0 | local function beginning | 本地函数开始 | +| LFE0 | local function ending | 本地函数结束 | +| LBB0 | local block beginning | 本地块开始 | +| LBE0 | local block ending | 本地块结束 | +| L | local labels | 本地标记 | + +## 汇编关联的信息 + + -fverbose-asm + +## 结构体 + +```cpp +typedef struct struct_t +{ + char c1; // 1 + short s1; // 2 + int i1; // 4 +} struct_t; + +struct_t data; +``` + +成员对齐,&i1 % 4 == 0 ; &s1 % 2 == 0 + +```cpp +typedef struct struct_t +{ + char c1; // 1 + short s1; // 2 + int i1; // 4 +} __attribute__((packed)) struct_t; + +struct_t data; +``` + +## 位操作 + +```cpp +typedef struct struct_t +{ + char c1 : 4; // 4 bit + char c2 : 2; // 2 bit + char c3 : 1; // 1 + char c4 : 1; // 1 +} __attribute__((packed)) struct_t; + +struct_t data; +``` + +## 结构体成员顺序 + +```cpp + +typedef struct struct_t +{ + char c1; + int i1; + char c2; + int i2; + char c3; + int i3; +} struct_t; + +typedef struct struct_t +{ + int i1; + int i2; + int i3; + + char c1; + char c2; + char c3; +} struct_t; + +struct_t data; +``` + +## 联合(共用体) + +```cpp +typedef union union_t +{ + char value; + struct_t m; +} union_t; + +union_t udata; +``` + +## 枚举 + +```cpp +typedef enum enum_t +{ + ENUM1 = 1, + ENUM2, + ENUM3 +} enum_t; + +enum_t edata = 345; +``` diff --git "a/x86_assembly/docs/28 gcc \345\206\205\350\201\224\346\261\207\347\274\226.md" "b/x86_assembly/docs/28 gcc \345\206\205\350\201\224\346\261\207\347\274\226.md" new file mode 100644 index 0000000..77ddb21 --- /dev/null +++ "b/x86_assembly/docs/28 gcc \345\206\205\350\201\224\346\261\207\347\274\226.md" @@ -0,0 +1,242 @@ +# gcc 内联汇编 + +## 基础内联汇编 + +```cpp +#include + +int main() +{ + asm("movl $1, %eax\n movl $0, %ebx\n int $0x80"); +} +``` + +```cpp +#include + +int main() +{ + asm( + "movl $1, %eax\n" + "movl $0, %ebx\n" + "int $0x80\n"); +} +``` + +## 使用全局变量 + +```cpp +#include + +int a = 10; +int b = 20; +int result; + +int main() +{ + // result = a + b; + asm( + "movl a, %eax\n" + "movl b, %edx\n" + "addl %edx, %eax\n" + "movl %eax, result"); + + printf("%d + %d = %d\n", a, b, result); +} +``` + +## 扩展内联汇编 / 使用局部变量 + +```cpp +asm ("assembly code": output : input : changed registers) +``` + +```cpp +"constraint"(variable) +``` + +| 约束 | 描述 | +| ---- | ------------------------------------ | +| a | 使用 eax 及相关寄存器 | +| b | 使用 ebx 及相关寄存器 | +| c | 使用 ecx 及相关寄存器 | +| d | 使用 edx 及相关寄存器 | +| S | 使用 esi 及相关寄存器 | +| D | 使用 edi 及相关寄存器 | +| r | 使用任何可用的通用寄存器 | +| q | 使用 eax,ebx,ecx,edx 之一 | +| A | 对于 64 位值使用 eax 和 edx 寄存器 | +| f | 使用浮点寄存器 | +| t | 使用第一个(顶部的)浮点寄存器 | +| u | 使用第二个浮点寄存器 | +| m | 使用变量的内存位置 | +| o | 使用偏移的内存位置 | +| V | 只使用直接内存位置 | +| i | 使用立即数整型 | +| n | 使用值已知的立即数整型 | +| g | 使用任何可用的寄存器或者任何内存位置 | + +| 输出修饰符 | 描述 | +| ---------- | -------------------------------------- | +| + | 可以读取和写入操作数 | +| = | 只能写入操作数 | +| % | 如果必要,操作数可以和下一个操作数切换 | +| & | 相关的寄存器只能用于输出 | + +扩展汇编中寄存器需要两个 % + +```cpp +#include + +int main() +{ + int a = 10; + int b = 20; + int result; + + // result = a + b; + asm volatile( + "addl %%edx, %%eax\n" + : "=a"(result) + : "a"(a), "d"(b)); + + printf("%d + %d = %d\n", a, b, result); +} +``` + +## 占位符 + +```cpp +#include + +int main() +{ + int a = 10; + int b = 20; + int result; + + // result = a + b; + asm volatile( + "addl %1, %2\n" + "movl %2, %0\n" + : "=r"(result) // %0 + : "r"(a), "r"(b)); + + printf("%d + %d = %d\n", a, b, result); +} +``` + +## 引用占位符 + +```cpp +#include + +int main() +{ + int a = 10; + int b = 20; + int result = 30; + + // result = result + a; + // result = a + b; + asm volatile( + "addl %1, %2\n" + "movl %2, %0\n" + : "=r"(result) // %0 + : "r"(a), "0"(result)); + + // printf("%d + %d = %d\n", a, b, result); + printf("result + %d = %d\n", a, result); +} +``` + +## 命名的占位符 + +```cpp +#include + +int main() +{ + int a = 10; + int b = 20; + int result; + + // result = a + b; + asm volatile( + "addl %[var2], %[var3]\n" + "movl %[var3], %[var1]\n" + : [var1] "=r"(result) // %0 + : [var2] "r"(a), [var3] "r"(b)); + + printf("%d + %d = %d\n", a, b, result); +} +``` + +## 改动的寄存器列表 + +```cpp +#include + +int main() +{ + int a = 10; + int b = 20; + int result; + + // result = a + b; + asm volatile( + "movl %[a], %%eax\n" + "movl %[b], %%edx\n" + "addl %%edx, %%eax\n" + "movl %%eax, %[result]\n" + : [result] "=r"(result) // %0 + : [a] "r"(a), [b] "r"(b) + : "%eax", "%edx"); + + printf("%d + %d = %d\n", a, b, result); +} +``` + +## 使用内存位置 + +```cpp +#include + +int main() +{ + int a = 10; + int b = 20; + int result; + + // result = a + b; + asm volatile( + "addl %[var2], %[var3]\n" + "movl %[var3], %[var1]\n" + : [var1] "=m"(result) // %0 + : [var2] "m"(a), [var3] "m"(b)); + + printf("%d + %d = %d\n", a, b, result); +} +``` + +## earlyclobber + +```cpp +#include + +int main() +{ + int a = 10; + int b = 20; + int result = 30; + + // result = a + b; + asm volatile( + "movl $10, %0\n" + "movl $20, %1\n" + : "=&r"(a) // %0 + : "r"(b)); + + printf("%d + %d = %d\n", a, b, result); +} +``` diff --git "a/x86_assembly/docs/29 \345\207\275\346\225\260\350\260\203\347\224\250\347\272\246\345\256\232.md" "b/x86_assembly/docs/29 \345\207\275\346\225\260\350\260\203\347\224\250\347\272\246\345\256\232.md" new file mode 100644 index 0000000..d886501 --- /dev/null +++ "b/x86_assembly/docs/29 \345\207\275\346\225\260\350\260\203\347\224\250\347\272\246\345\256\232.md" @@ -0,0 +1,122 @@ +# 函数调用约定 + +## C declaration (cdecl) + +- 参数从右向左入栈 +- 函数的返回值存储在 eax +- eax, ecx, edx 由调用者保存 +- ebp, ebx, esi, edi, esp 由被调用者保存 +- 由调用者清理栈空间(弹出参数) add esp, n + +> ABI 约定 + +Application Binary Interface + +--- + +## 汇编和 C 的相互调用 + +```cpp +#include + +extern int add(int a, int b); + +int main() +{ + int i = 5; + int j = 10; + int k = add(i, j); + printf("%d + %d = %d\n", i, j, k); +} +``` + +```s +[bits 32] + +extern printf + +section .text +global add +add: + push ebp + mov ebp, esp + + push message + call printf + add esp, 4 + + ; ebp ; ebp + 0 + ; eip ; ebp + 4 + ; a ; ebp + 8 + ; b ; ebp + 12 + + mov eax, [ebp + 8]; eax = a + add eax, [ebp + 12]; b + + leave + ret + +section .data + + message db "add called!!!", 10, 0 +``` + +## 系统调用 + +32 位保护模式 + +内中断会引起特权级的转换,很低效 + +栈来传递参数 + +0 - 栈 +3 - 栈 + +- eax +- ebx +- ecx +- edx +- esi +- edi + +## fastcall + +- ecx, edx 传递前两个参数 +- 三个以上参数从右向左入栈 +- eax, ecx, edx 由调用者保存 +- ebp, ebx, esi, edi, esp 由被调用者保存 +- 由被调用者清理栈空间(弹出参数) + +```cpp + +#include + +extern int add(int a, int b); +extern int __attribute__((fastcall)) sub(int a, int b); + +int main() +{ + int i = 5; + int j = 10; + // int k = add(i, j); + int k = sub(i, j); + printf("%d - %d = %d\n", i, j, k); +} +``` + +```s +global sub +sub: + push ebp + mov ebp, esp + + mov eax, ecx + sub eax, edx + + leave + ret +``` + +## 栈帧 + + -fomit-frame-pointer diff --git "a/x86_assembly/docs/30 \351\223\276\346\216\245\345\222\214\345\212\240\350\275\275.md" "b/x86_assembly/docs/30 \351\223\276\346\216\245\345\222\214\345\212\240\350\275\275.md" new file mode 100644 index 0000000..6a297c4 --- /dev/null +++ "b/x86_assembly/docs/30 \351\223\276\346\216\245\345\222\214\345\212\240\350\275\275.md" @@ -0,0 +1,152 @@ +# 链接和加载 + +```cpp +#include "compile.h" + +void function() +{ +} + +int main(int argc, char const *argv[]) +{ + function(); + return 0; +} +``` + +```cpp +void function(); +``` + +## 预处理 + + gcc $(CFLAGS) $(DEBUG) -E $< -o $@ + +```cpp +# 0 "compile.cc" +# 1 "/home/steven/source/github/computer/x86_assembly/analysis//" +# 0 "" +# 0 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 0 "" 2 +# 1 "compile.cc" +# 1 "compile.h" 1 + +void function(); +# 2 "compile.cc" 2 + +void function() +{ +} + +int main(int argc, char const *argv[]) +{ + function(); + return 0; +} +``` + +## 编译 + +- 词法分析 +- 语法分析 +- 语义分析 +- 中间代码生成 +- 指令选择 +- 寄存器分配 + + gcc $(CFLAGS) -S $< -o $@ + +```s + .file "compile.c" + .text + .globl function + .type function, @function +function: + nop + ret + .size function, .-function + .globl main + .type main, @function +main: + call function + movl $0, %eax + ret + .size main, .-main + .ident "GCC: (GNU) 11.1.0" + .section .note.GNU-stack,"",@progbits +``` + +## 汇编 + + gcc $(CFLAGS) $(DEBUG) -c $< -o $@ + as -32 $< -o $@ + +生成二进制文件 + +## 链接 + + ld -m elf_i386 -static $< -o $@ -e main + +生成可执行文件 + +## gcc 集成环境 + + gcc compile.cc -o compile.out --verbose + +--- + + /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/cc1plus -quiet -v -D_GNU_SOURCE compile.cc -quiet -dumpdir compile.out- -dumpbase compile.cc -dumpbase-ext .cc -mtune=generic -march=x86-64 -version -o /tmp/cciKDCSK.s + +--- + + as -v --64 -o /tmp/cczjiqmy.o /tmp/cciKDCSK.s + + +--- + +```sh +/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/collect2 +-plugin /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so +-plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/lto-wrapper +-plugin-opt=-fresolution=/tmp/ccvrMGma.res +-plugin-opt=-pass-through=-lgcc +-plugin-opt=-pass-through=-lgcc_s +-plugin-opt=-pass-through=-lc +-plugin-opt=-pass-through=-lgcc +-plugin-opt=-pass-through=-lgcc_s +--build-id +--eh-frame-hdr +--hash-style=gnu +-m elf_x86_64 +-dynamic-linker +/lib64/ld-linux-x86-64.so.2 +-pie +-o compile.out +/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/Scrt1.o +/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/crti.o +/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/crtbeginS.o +-L/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0 +-L/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib +-L/lib/../lib +-L/usr/lib/../lib +-L/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../.. +/tmp/cczjiqmy.o +-lgcc +--push-state +--as-needed +-lgcc_s +--pop-state +-lc +-lgcc +--push-state +--as-needed +-lgcc_s +--pop-state +/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/crtendS.o +/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/crtn.o +``` + +## 极简内核 + + diff --git "a/x86_assembly/docs/31 \345\255\227\347\254\246\344\270\262\345\244\204\347\220\206.md" "b/x86_assembly/docs/31 \345\255\227\347\254\246\344\270\262\345\244\204\347\220\206.md" new file mode 100644 index 0000000..2896fa9 --- /dev/null +++ "b/x86_assembly/docs/31 \345\255\227\347\254\246\344\270\262\345\244\204\347\220\206.md" @@ -0,0 +1,113 @@ +# 字符串处理 + +## 内存拷贝 + +```cpp +void* memcpy( void *dest, const void *src, size_t count ); +char *strcpy( char *dest, const char *src ); +``` + +```cpp +void *memcpy(void *dest, const void *src, size_t count) +{ + char *dptr = dest; + const char *sptr = src; + for (size_t i = 0; i < count; i++) + { + dptr[i] = sptr[i]; + } + return dest; +} + +char message[] = "hello world!!!\n"; +char buffer[sizeof(message)]; + +int main(int argc, char const *argv[]) +{ + memcpy(buffer, message, sizeof(message)); + return 0; +} +``` + +```s +global amemcpy +amemcpy: + push ebp + mov ebp, esp + + ; ebp 0 + ; eip 4 + ; dest 8 + ; src 12 + ; count 16 + + mov ecx, [ebp + 16]; count loop + mov esi, [ebp + 12]; src + mov edi, [ebp + 8]; dest + + cld; df = 0 + ; std; df = 1 + rep movsb + + leave + ret +``` + +---- + +ds:esi --> es:edi + +ds:si --> es:di + +- movsb 传送一个字节 +- movsw +- movsd / `movsl` + +### 重复指令 + +| 指令 | 描述 | +| ----- | ------------ | +| rep | 无条件重复 | +| repe | 等于时重复 | +| repz | 为零时重复 | +| repne | 不等于时重复 | +| repnz | 不为零时重复 | + +## lods / stos + +- lodsb (ds:esi) --> al +- lodsw (ds:esi) --> ax +- lodsd (ds:esi) --> eax + +- stosb (es:edi) <-- al +- stosw (es:edi) <-- ax +- stosd (es:edi) <-- eax + +```cpp +void *memset( void *dest, int ch, size_t count ); +``` + +## cmps + +- cmpsb +- cmpsw +- cmpsd + +```cpp +int memcmp( const void* lhs, const void* rhs, size_t count ); +``` + +## scas + +- scasb +- scasw +- scasd + +```cpp +void* memchr( const void* ptr, int ch, size_t count ); +``` + +## 条件传送指令 + +- CMOVE +- CMOVZ \ No newline at end of file diff --git "a/x86_assembly/docs/32 \346\225\264\346\225\260\347\232\204\346\211\251\345\261\225\345\222\214\346\272\242\345\207\272.md" "b/x86_assembly/docs/32 \346\225\264\346\225\260\347\232\204\346\211\251\345\261\225\345\222\214\346\272\242\345\207\272.md" new file mode 100644 index 0000000..d412d9d --- /dev/null +++ "b/x86_assembly/docs/32 \346\225\264\346\225\260\347\232\204\346\211\251\345\261\225\345\222\214\346\272\242\345\207\272.md" @@ -0,0 +1,31 @@ +# 整数的扩展和溢出 + +## 整数的扩展 + +无符号扩展 + + movzx ebx, al + +有符号扩展 + + movsx ebx, al; 0xffffffff + +## 溢出 + +试图表示自身表示不了的数,就是溢出。 + +无符号数 --> CF + +有符号数 --> OF + +127 = 0b_0111_1111 + +0b1000_0000 = -128 + +-127 = 0 - 127 = 0b10000_0000 - 0b_0111_1111 + += 0b_1000_0001 = -127 + +-127 - 1 = 0b_1000_0000 = -128 + +$$x < 0 \Rightarrow x_b + |x| = 0 \Rightarrow x_b = 0 - |x|$$ diff --git "a/x86_assembly/docs/33 \346\265\256\347\202\271\346\225\260\347\232\204\350\241\250\347\244\272.md" "b/x86_assembly/docs/33 \346\265\256\347\202\271\346\225\260\347\232\204\350\241\250\347\244\272.md" new file mode 100644 index 0000000..4a2ebb5 --- /dev/null +++ "b/x86_assembly/docs/33 \346\265\256\347\202\271\346\225\260\347\232\204\350\241\250\347\244\272.md" @@ -0,0 +1,125 @@ +# 浮点数的表示 + +## 负数补码的运算 + +$$x < 0 \Rightarrow x_b + |x| = 0 \Rightarrow x_b = 0 - |x|$$ + +> 负数补码,正数按位取反再加一 + +10000101 +01111010 + +11111111 = -1 + +正数按位取反 + 1 = 负数的补码 + +$$ +|x|_i + |x| = -1 \\ +|x|_i + |x| + 1 = 0 \\ +x_b + |x| = 0 \\ +\Rightarrow |x|_i + 1 = x_b +$$ + +## 定点数 + +定点整数 + +$$ +0b101. = 1 \times 2^2 + 0 \times 2^1 + 1 \times 2^0 = 4 + 0 + 1 = 5 +$$ + +定点小数 + +$$ +0b0.101 = 1 \times 2^{-1} + 0 \times 2^{-2} + 1 \times 2^{-3} = {1 \over 2} + 0 + {1 \over 8} = {5 \over 8} +$$ + +$$ +\sum {1 \over 2^n} n \in N +$$ + +定点小数负数补码 + +0b1.101 + +x_b + |x| = 0 + +0 - 0.101 = 10.000 - 0.101 = 1011 + +$$x_b = 2 - |x|$$ + +## 浮点数 + +$$ +2.33 \times 10^{5} \\ +0.233 \times 10^{6} \\ +$$ + +- 底数 --> 10 +- 指数 --> 5 +- 系数 --> 2.33 + +$$ +0b1.01 \times 2^{0b10} \\ +0b0.101 \times 2^{0b11} \\ +$$ + +- 底数 --> 2 +- 指数(阶码) --> 10 +- 系数(尾数) --> 0b1.01 + +## IEEE 754 标准 + +| 类型 | 长度 | 符号位 | 指数 | 尾数 | 有效数字 | 范围 | +| -------- | ---- | ------ | ---- | ---- | -------- | ----------------------------------------------- | +| 单精度 | 32 | 1 | 8 | 23 | 24 | $1.18 \times 10^{-38} \sim 3.40 \times 10^{38}$ | +| 双精度 | 64 | 1 | 11 | 52 | 53 | $2.23 \times 10^{-308} \sim 1.79 \times 10^{308}$ | +| 扩展精度 | 80 | 1 | 15 | 63 | 63 | $3.37 \times 10^{-4932} \sim 1.18 \times 10^{4932}$ | + + +## 指数(阶码)的移码 + +$2^{e - 1} - 1 = 127$ + +-127 ~ 128 + +## 各种码存在的意义 + +有符号数 + +### 原码 + +原码是最直观的形式,最高位为符号位,后面是二进制数 + +### 补码 + +CPU 只能做加法,全加器 ALU + +计算机要做减法, + +A - B = C + +A + D = C + ++D = -B + +### 反码 + +补码 -> 反码 + 1 + +### 移码 + +浮点数对阶 + +$$ +\begin{aligned} +& 1.2 \times 10^{3} + 3.4 \times 10^5 \\ +=& 0.012 \times 10^{5} + 3.4 \times 10^5 \\ +=& 3.412 \times 10^5 \\ +\end{aligned} +$$ + +比较两个指数的大小 + +0b00000000 表示最小的数 = -127 +0b11111111 表示最大的数 = 128 diff --git "a/x86_assembly/docs/34 \345\237\272\347\241\200\346\265\256\347\202\271\350\277\220\347\256\227.md" "b/x86_assembly/docs/34 \345\237\272\347\241\200\346\265\256\347\202\271\350\277\220\347\256\227.md" new file mode 100644 index 0000000..65a7a7a --- /dev/null +++ "b/x86_assembly/docs/34 \345\237\272\347\241\200\346\265\256\347\202\271\350\277\220\347\256\227.md" @@ -0,0 +1,116 @@ +# 基础浮点运算 + +## FPU Float Point Unit + +- 8086 / 8087 +- 80286 / 80287 +- 80386 / 80387 +- 80486 / x87 + +## 寄存器 + +- 8 个 80 位的数据寄存器: ST0 - ST1 + - 形成循环堆栈 + - 栈顶是 ST0 +- 3 个 16 位的控制寄存器: + - 控制 + - 状态 + - 标记 + +## 状态寄存器 + +| 状态位 | 描述 | +| ------- | ---------------------- | +| 0 | 非法操作异常标志 | +| 1 | 非规格化操作数异常标志 | +| 2 | 除数为零异常标志 | +| 3 | 溢出异常标志 | +| 4 | 下溢异常标志 | +| 5 | 精度异常标志 | +| 6 | 堆栈错误 | +| 7 | 错误汇总状态 | +| 8 | 条件代码位0 C0 | +| 9 | 条件代码位1 C1 | +| 10 | 条件代码位2 C2 | +| 11 - 13 | 堆栈顶部指针 | +| 14 | 条件代码位3 C3 | +| 15 | FPU 繁忙标志 | + + fstsw; 保存状态寄存器 + +## 控制寄存器 + +| 控制位 | 描述 | +| ------- | ---------------------- | +| 0 | 非法操作异常掩码 | +| 1 | 非规格化操作数异常掩码 | +| 2 | 除数为零异常掩码 | +| 3 | 溢出异常掩码 | +| 4 | 下溢异常掩码 | +| 5 | 精度异常掩码 | +| 6 - 7 | 保留 | +| 8 - 9 | 精度控制 | +| 10 - 11 | 舍入控制 | +| 12 | 无穷大控制 | +| 13 - 15 | 保留 | + +精度控制: + +- 00 单精度 +- 01 未使用 +- 10 双精度 +- 11 扩展精度(默认) + +舍入控制: + +- 00 舍入到最近值(默认) +- 01 向下舍入(负无穷大) +- 10 向上舍入 (正无穷大) +- 11 向零舍入 + + fstcw; 保存控制寄存器 + fldcw; 加载控制寄存器 + +## 标记寄存器 + +- 00 一个合法的扩展双精度值 +- 01 零值 +- 10 特殊的浮点值 +- 11 无内容(空) + +## 基础浮点运算指令 + +| 指令 | 描述 | +| ----- | ------------ | +| FADD | 浮点加法 | +| FDIV | 浮点除法 | +| FDIVR | 反向浮点除法 | +| FMUL | 浮点乘法 | +| FSUB | 浮点减法 | +| FSUBR | 反向浮点减法 | + +```s +FADD source +; 内存中的 32 位或者 64 位值和 st0 寄存器相加 + +FADD st0, stx +; stx 和 st0 相加,结果存储到 st0 中 + +FADD stx, st0; +; st0 和 stx 相加,结果存储到 stx 中 + +FADDP stx, st0; +; st0 和 stx 相加,结果存储到 stx 中,井且弹出 st0 + +FADDP +; st0 和 st1 相加,结果存储到 st1 中,并且弹出 st0 + +FIADD source +; 16 位或者 32 位整数值和 st0 相加,结果存储到 st0 中 +``` + +`((43.65 / 22) + (76.34 * 3.1)) / ((12.43 * 6) - (140.2 / 94.21))` + +$$ +{\displaystyle{43.65 \over 22} + 76.34 \times 3.1 \over 12.43 \times 6 - \displaystyle{ 140.2 \over 94.21}} \approx 3.264907633729943 +$$ diff --git "a/x86_assembly/docs/35 \351\253\230\347\272\247\346\265\256\347\202\271\350\277\220\347\256\227.md" "b/x86_assembly/docs/35 \351\253\230\347\272\247\346\265\256\347\202\271\350\277\220\347\256\227.md" new file mode 100644 index 0000000..4c06793 --- /dev/null +++ "b/x86_assembly/docs/35 \351\253\230\347\272\247\346\265\256\347\202\271\350\277\220\347\256\227.md" @@ -0,0 +1,59 @@ +# 高级浮点运算 + +## 预设浮点值 + +| 指令 | 描述 | +| ------ | ----------- | +| FLD1 | $+1.0$ | +| FLDL2T | $\log_2 10$ | +| FLDL2E | $\log_2 e$ | +| FLDPI | $\pi$ | +| FLDLG2 | $\log_{10} 2$ | +| FLDLN2 | $\ln 2$ | +| FLDZ | $+0.0$ | + +## 高级浮点指令 + +| 指令 | 描述 | +| ------- | ------------------------------------------------ | +| FABS | 计算 ST0 中的值的绝对值 | +| FCHS | 改变 ST0 中的值的符号 | +| FRNDINT | 把 ST0 中的值舍入到最近的整数 | +| FSQRT | 计算 ST0 中的值的平方根 | +| FSIN | 计算 ST0 中的值的正弦 | +| FCOS | 计算 ST0 中的值的余弦 | +| FSINCOS | 计算 ST0 中的值的正弦和余弦 | +| FPTAN | 计算 $st0 =\tan(st0)$ 并 `fld1` | +| FPATAN | 计算 $st1 =\arctan (st1/st0)$ 并弹栈 | +| FPREM | 计算 ST0 中的值除以 ST1 中的值的余数 | +| FPREM1 | 计算 ST0 中的值除以 ST1 中的值的 IEEE 余数 | +| F2XM1 | 计算 $2^{st0} - 1$ $st0 \in (-1.0, 1.0)$ | +| FSCALE | 计算 ST0 乘以 2 的 ST1 次乘方 | +| FYL2X | 计算 $ST1 \cdot \log_2 ST0$ | +| FYL2XP1 | 计算 $ST1 \cdot \log_2 (ST0 + 1)$ | + +## 浮点余数 + +19.8 / 3.4 = 5.8235294117647065 + +### Intel + +商 = 5 + +19.8 - (3.4 * 5) + +向零取整 - 整数向下取整,负数向上取整 + +### IEEE + +向上取整 + +商 = 6 + +19.8 - (3.4 * 6) + +## 数值计算 + +- 代数数 $\sqrt{2}$ +- 超越数 $\pi$ +- 非线性函数的计算 $\sin \cos \int$ diff --git "a/x86_assembly/docs/36 \346\265\256\347\202\271\346\235\241\344\273\266\345\210\206\346\224\257.md" "b/x86_assembly/docs/36 \346\265\256\347\202\271\346\235\241\344\273\266\345\210\206\346\224\257.md" new file mode 100644 index 0000000..03065fd --- /dev/null +++ "b/x86_assembly/docs/36 \346\265\256\347\202\271\346\235\241\344\273\266\345\210\206\346\224\257.md" @@ -0,0 +1,42 @@ +# 浮点条件分支 + +## fcom 系列指令 + +| 指令 | 描述 | +| ------------ | ----------------------------------------------- | +| fcom | 比较 st0 和 st1 | +| fcom stx | 比较 st0 和 stx | +| fcom source | 比较 st0 和 32 位或者 64 位的内存值 | +| fcomp | 比较 st0 和 st1,并弹出堆栈 | +| fcomp stx | 比较 st0 和 stx,并弹出堆栈 | +| fcomp source | 比较 st0 和 32 位或者 64 位的内存值,并弹出堆栈 | +| fcompp | 比较 st0 和 st1,并弹出堆栈两次 | +| ftst | 比较 st0 和值 0.0 | + +## 状态寄存器条件状态 + +| 条件 | C3 | C2 | C0 | +| --------------- | --- | --- | --- | +| `st0 > source` | 0 | 0 | 0 | +| `st0 < source` | 0 | 0 | 1 | +| `st0 == source` | 1 | 0 | 0 | + + fstsw + sahf + +## fcomi 系列指令 + +| 指令 | 描述 | +| ------- | -------------------------------------------- | +| fcomi | 比较 st0 和 stx | +| fcomip | 比较 st0 和 stx,并弹出堆栈 | +| fucomi | 在比较之前检查无序值 | +| fucomip | 在比较之前检查无序值,并且在比较之后弹出堆栈 | + +fcomi 指令的输出使用 EFLAGS 寄存器,如下表所示。 + +| 条件 | ZF | PF | CF | +| ------------ | --- | --- | --- | +| `st0 > stx` | 0 | 0 | 0 | +| `st0 < stx` | 0 | 0 | 1 | +| `st0 == stx` | 1 | 0 | 0 | diff --git "a/x86_assembly/docs/37 BCD \347\240\201\345\217\212\345\205\266\350\277\220\347\256\227.md" "b/x86_assembly/docs/37 BCD \347\240\201\345\217\212\345\205\266\350\277\220\347\256\227.md" new file mode 100644 index 0000000..5c4c85d --- /dev/null +++ "b/x86_assembly/docs/37 BCD \347\240\201\345\217\212\345\205\266\350\277\220\347\256\227.md" @@ -0,0 +1,161 @@ +# BCD 码及其运算 + +Binary Coded Decimal / 二进制编码的十进制数 + +int ; // 除十取余 + +char number[10000]; // 0x30 + 0 = 0 0x31 + +- 不打包的 BCD 码 / 一个字节表示一个十进制位 +- 打包的 BCD 码 / 一个字节表示两个十进制位 + +## 运算 + +- AAA: 调整加法操作的结果 +- AAS: 调整减法操作的结果 +- AAM: 调整乘法操作的结果 +- AAD: 准备除法操作的被除数 + +## 加法 + +```s +section .data + + value1 dd 0x05060708 + value2 dd 0x01020304 + value3 dd 0 + +; 6912 + +section .text +global main +main: + clc + mov ecx, 4 + xor edi, edi +loop1: + mov al, [value1 + edi] + adc al, [value2 + edi] + aaa + mov [value3, + edi], al + inc edi + loop loop1 + + ret +``` + +## 减法 + +```s +section .data + + value1 dd 0x05060708 + value2 dd 0x03090809 + value3 dd 0 + +; 1689 + +section .text +global main +main: + clc + mov ecx, 4 + xor edi, edi +loop1: + mov al, [value1 + edi] + sbb al, [value2 + edi] + aas + mov [value3, + edi], al + inc edi + loop loop1 + + ret +``` + +## 乘法和除法 + +```s +section .data + + value1 dd 0x05060708 + value2 dd 0x03090809 + value3 dd 0 + +; 1689 + +section .text +global main +main: + + mov al, [value1] + mul byte [value2] + aam + + mov ax, [value1] + aad + div byte [value2] + + ret +``` + +## 打包的 BCD 码 + +DAA: 调整 ADD 或者 ADC 指令的结果。 +DAS: 调整 SUB 或者 SBB 指令的结果。 + + +```s +section .data + + value1 dd 0x12345678 + value2 dd 0x12345678 + value3 dd 0 + +; 24,691,356 + +section .text +global main +main: + clc + mov ecx, 4 + xor edi, edi +loop1: + mov al, [value1 + edi] + adc al, [value2 + edi] + daa + mov [value3, + edi], al + inc edi + loop loop1 + + ret +``` + +```s +section .data + + value1 dd 0x12345945 + value2 dd 0x03234098 + value3 dd 0 + +; 9,111,847 + +section .text +global main +main: + clc + mov ecx, 4 + xor edi, edi +loop1: + mov al, [value1 + edi] + sbb al, [value2 + edi] + das + mov [value3, + edi], al + inc edi + loop loop1 + + ret +``` + +## AF 标记 + +用于调整打包的 BCD 码 diff --git "a/x86_assembly/docs/38 \345\256\217.md" "b/x86_assembly/docs/38 \345\256\217.md" new file mode 100644 index 0000000..f1033ef --- /dev/null +++ "b/x86_assembly/docs/38 \345\256\217.md" @@ -0,0 +1,60 @@ +# 宏 + +预处理(预编译)指令 + +## 预处理 + + nasm -E %< -o %@ + +## 条件汇编 + +```s +%ifndef MACRO_INC +%define MACRO_INC + +extern printf +extern exit + +%endif +``` + +## 宏函数 + +```s +%include "macro.inc" + +%define square(x) (x * x) +%define add(x, y) (x + y) + +section .text +global main +main: + mov eax, square(10) + mov ebx, add(5, 3) + ret +``` + +## 多行宏 + +```s +; 参数: +; - 基地址 +; - 界限 +; - type +; - segment +; - dpl +; - present +; - long_mode +; - big +; - granularity +%macro descriptor 9 + dw %2 & 0xffff; limit_low + dw %1 & 0xffff; base_low_16 + db (%1 >> 16) & 0xff; base_low_8 + db %3 | (%4 << 4) | (%5 << 6) | (%6 << 7) + db ((%2 >> 16) & 0xf) | (%7 << 5) | (%8 << 6) | (%9 << 7) + db (%1 >> 24) & 0xff +%endmacro + +descriptor 0x10000, 0xfff, 0b0010, 1, 0, 1, 0, 1, 0 +``` diff --git "a/x86_assembly/docs/39 \344\270\200\344\272\233\350\241\245\345\205\205\350\257\264\346\230\216.md" "b/x86_assembly/docs/39 \344\270\200\344\272\233\350\241\245\345\205\205\350\257\264\346\230\216.md" new file mode 100644 index 0000000..c041744 --- /dev/null +++ "b/x86_assembly/docs/39 \344\270\200\344\272\233\350\241\245\345\205\205\350\257\264\346\230\216.md" @@ -0,0 +1,36 @@ +# 一些补充说明 + +## masm 兼容性 + +王爽 《汇编语言》,8086 CPU 在 DOS 操作系统下的应用程序编程 + +- `segment` +- `assume` +- `ptr` +- `offset` + +masm - 1981 + +- 386 + +8086 的寻址方式 + +16 -> 64K + +有效地址 = 段寄存器 << 4 + 偏移地址 + +## 高级 x86 指令 + +- SIMD - Single Instruction Multiple Data +- MMX - MultiMedia Extension - 奔腾2 +- SSE - Streaming SIMD Extension - 奔腾4 + +## 展望 + +- ELF 文件解析 +- 操作系统 +- 编译器 - 高级语言 --> 汇编语言 +- 汇编器 - 汇编语言 --> ELF 文件 +- 数据结构和算法 +- 计算机网络 +- 数据库 diff --git "a/x86_assembly/docs/Ubuntu \351\205\215\347\275\256 bochs \347\232\204\346\226\271\346\263\225.md" "b/x86_assembly/docs/Ubuntu \351\205\215\347\275\256 bochs \347\232\204\346\226\271\346\263\225.md" new file mode 100644 index 0000000..ede5e2a --- /dev/null +++ "b/x86_assembly/docs/Ubuntu \351\205\215\347\275\256 bochs \347\232\204\346\226\271\346\263\225.md" @@ -0,0 +1,85 @@ +# Ubuntu 配置 bochs 的方法 + +## 安装 bochs + +执行命令: + + sudo apt install bochs + sudo apt install bochs-x + +其中最重要的是 `bochs-x` 这个包,包括了 gui 插件。 + +## 配置 Bochs + +执行命令: + + bochs + +选择 `4. Save options to...` + +然后输入文件名 `bochsrc` 直接保存 + +选择 `7. Quit now` 退出 bochs + +然后创建虚拟磁盘,输入命令 + + bximage -hd -mode="flat" -size=60 -q master.img + +这样就可以创建一个 16M 的硬盘。 + +输出的最下面输出了以下内容: + +```text +The following line should appear in your bochsrc: + ata0-master: type=disk, path="master.img", mode=flat +``` + +也就是说要将上面这样代码写到 `bochsrc` 中, + +然后将 `display_library: x` 改成 `display_library: x, options="gui_debug"` 以支持 GUI 的调试方式。 + +将 `boot: floppy` 改成 `boot: disk`,以支持从硬盘启动。 + +## 编辑代码 + +输入命令: + + touch hello.asm + +然后使用文本编辑起写入如下内容: + +```s +mov ax, 0xb800 +mov ds, ax; 将代码段设置为 0xb800 + +mov byte [0], 'T'; 修改屏幕第一个字符为 T + +; 下面阻塞停下来 +halt: + jmp halt + +times 510 - ($ - $$) db 0 ; 用 0 填充满 510 个字节 +db 0x55, 0xaa; 主引导扇区最后两个字节必须是 0x55aa +``` + +安装 `nasm` 汇编器: + + sudo apt install nasm + +然后汇编成二进制代码: + + nasm -f bin hello.asm -o hello.bin + +然后将主引导扇区写入硬盘: + + dd if=hello.bin of=master.img bs=512 count=1 conv=notrunc + +启动 `bochs` 测试环境: + + bochs -q + +## 参考资料 + +- [修改ubuntu 18.04的sources.list源为阿里或清华镜像的方法_Linux_脚本之家 (jb51.net)](https://www.jb51.net/article/193933.htm) +- [x86 汇编语言 - 01 配置开发环境 (ccyg.studio)](http://blog.ccyg.studio/article/eedcc300-35f4-4174-9622-c336aa8d7881/) +- diff --git a/x86_assembly/docs/graph1.md b/x86_assembly/docs/graph1.md new file mode 100644 index 0000000..f8144d6 --- /dev/null +++ b/x86_assembly/docs/graph1.md @@ -0,0 +1,26 @@ +```mermaid +flowchart TD + subgraph CPU + NMI[NMI - 不可屏蔽中断] + INTR[INTR - 可屏蔽中断] + end + subgraph PICM[PIC - 可编程中断控制器 - 主片] + CLC[时钟] + KB[键盘] + SLAVE[级联从片] + FLOPPY[软盘] + end + subgraph PICS[PIC - 可编程中断控制器 - 从片] + RTC[实时时钟] + HD[硬盘] + MOUSE[鼠标] + end + PICM --> INTR + PICS --> PICM +``` + + +```mermaid +flowchart LR +取指 --> 译码 --> 执行 --> 中断 +``` \ No newline at end of file diff --git a/x86_assembly/docs/images/80286-segment descriptor.jpg b/x86_assembly/docs/images/80286-segment descriptor.jpg new file mode 100644 index 0000000..7348763 Binary files /dev/null and b/x86_assembly/docs/images/80286-segment descriptor.jpg differ diff --git a/x86_assembly/docs/images/80386-segment descriptor.jpg b/x86_assembly/docs/images/80386-segment descriptor.jpg new file mode 100644 index 0000000..ca6da81 Binary files /dev/null and b/x86_assembly/docs/images/80386-segment descriptor.jpg differ diff --git a/x86_assembly/docs/readme.md b/x86_assembly/docs/readme.md new file mode 100644 index 0000000..2cf9001 --- /dev/null +++ b/x86_assembly/docs/readme.md @@ -0,0 +1,349 @@ +# x86 汇编语言 + +## 参考资料 + +[参考资料](./参考资料.md) + +## 寄存器 + +| 寄存器 | 描述 | +| ------ | ------------------ | +| AX | 累加结果数据 | +| BX | 数据段数据指针 | +| CX | 字符串和循环计数器 | +| DX | I/O 指针 | +| DI | 目的数据指针 | +| SI | 源数据指针 | +| SP | 栈指针 | +| BP | 栈数据指针 | + +| 寄存器 | 高八位 | 低八位 | +| ------ | ------ | ------ | +| AX | AH | AL | +| BX | BH | BL | +| CX | CH | CL | +| DX | DH | DL | + +| 段寄存器 | 描述 | +| -------- | ------------ | +| CS | 代码段寄存器 | +| DS | 数据段寄存器 | +| SS | 栈段寄存器 | +| ES | 额外的寄存器 | + +- IP +- FLAG / PSW + +## 寻址方式 + +物理地址 = 段地址 * 16 + 偏移地址 + +16 $2^{16} = 64K$ + +1M $2^{20}$ + +20 - 16 = 4 + +段寄存器 + +偏移地址 + 段地址寄存器 = 32 + +12 + +段地址 << 4 + 偏移地址 + +## 标志寄存器 + +| 位 | 标志 | 英文 | 描述 | +| --- | ---- | --------- | ------------ | +| 0 | CF | Carry | 进位标志 | +| 1 | | | | +| 2 | PF | Parity | 奇偶标志 | +| 3 | | | | +| 4 | AF | Auxiliary | 辅助进位标志 | +| 5 | | | | +| 6 | ZF | Zero | 零标志 | +| 7 | SF | Sign | 符号标志 | +| 8 | TF | Trap | 陷阱标志 | +| 9 | IF | Interrupt | 中断允许标志 | +| 10 | DF | Direction | 方向标志 | +| 11 | OF | Overflow | 溢出标志 | + + +## 转移指令 + +8086 cs:ip 下一条指令的地址,物理地址 = cs << 4 + ip + +jmp short start 占用两个字节,jmp 偏移数量,-128 - 127 +jmp near start 占三个字节 -32768 - 32767 + + +8086 物理地址 = 段地址 << 4 + 偏移地址 + +64KB 内存空间 + +jmp far cs:ip + +### 补码 + +负数的补码是原码取反再加一 + +x + 1 = 0 -> x = -1 + +0b1111_1111 = -1 +0b1111_1110 = -2 + +f_e 0xfe +0b1111_1011 = 0xfb = -5 + + +- JZ/JNZ : 结果为零/不为零则转移 +- JS/JNS : 结果为负/为正则转移 +- JO/JNO : 溢出/不溢出则转移 +- JP/JNP : 奇偶位为1/为0则转移 +- JB/JNB : 低于/不低于则转移 +- JBE/JNBE : 低于等于/高于则转移 +- JL/JNL : 小于/不小于则转移 +- JLE/JNLE : 小于等于/大于则转移 +- JCXZ : CX为零则转移 + +| 比较结果 | 英文 | 指令 | 标志 | +| ---------- | -------------------- | ---- | ------------------- | +| 等于 | Equal | je | ZF = 1 | +| 不等于 | Not Equal | jne | ZF = 0 | +| 大于 | Greater | jg | ZF = 0 and SF = OF | +| 大于等于 | Greater or Equal | jge | SF = 0F | +| 不大于 | Not Greater | jng | ZF = 1 or SF != OF | +| 不大于等于 | Not Greater or Equal | jnge | SF != OF | +| 小于 | Less | jl | SF != OF | +| 小于等于 | Less or Equal | jle | ZF = 1 and SF != OF | +| 不小于 | Not Less | jnl | SF = OF | +| 不小于等于 | Not Less or Equal | jnle | ZF = 0 and SF = 0f | +| 高于 | Above | ja | CF = 0 and ZF = 0 | +| 高于等于 | Above or Equal | jae | CF = 0 | +| 不高于 | Not Above | jna | CF = 1 or ZF = 1 | +| 不高于等于 | Not Above or Equal | jnae | CF = 1 | +| 低于 | Below | jb | CF = 1 | +| 低于等于 | Below or Equal | jbe | CF = 1 or ZF = 1 | +| 不低于 | Not Below | jnb | CF = 0 | +| 不低于等于 | Not Below or Equal | jnbe | CF = 0 and ZF = 0 | +| 偶 | Parity Even | jpe | PF = 1 | +| 奇 | Parity Odd | jpo | PF = 0 | + + +## 堆栈和函数 + +程序的指令的地址 cs:ip + +栈顶的指针 ss:sp + +push / pop + + +## 内中断和异常 + +远调用 + +jmp short start 占用两个字节,jmp 偏移数量,-128 - 127 +jmp near start 占三个字节 -32768 - 32767 +jmp far + +call function; push ip ; jmp function +call far function; push cs; push ip; jmp function + + +内中断 + +### 内存布局 + +| 起始地址 | 结束地址 | 大小 | 用途 | +| --------- | --------- | -------- | ------------------ | +| `0x000` | `0x3FF` | 1KB | 中断向量表 | +| `0x400` | `0x4FF` | 256B | BIOS 数据区 | +| `0x500` | `0x7BFF` | 29.75 KB | 可用区域 | +| `0x7C00` | `0x7DFF` | 512B | MBR 加载区域 | +| `0x7E00` | `0x9FBFF` | 607.6KB | 可用区域 | +| `0x9FC00` | `0x9FFFF` | 1KB | 扩展 BIOS 数据区 | +| `0xA0000` | `0xAFFFF` | 64KB | 用于彩色显示适配器 | +| `0xB0000` | `0xB7FFF` | 32KB | 用于黑白显示适配器 | +| `0xB8000` | `0xBFFFF` | 32KB | 用于文本显示适配器 | +| `0xC0000` | `0xC7FFF` | 32KB | 显示适配器 BIOS | +| `0xC8000` | `0xEFFFF` | 160KB | 映射内存 | +| `0xF0000` | `0xFFFEF` | 64KB-16B | 系统 BIOS | +| `0xFFFF0` | `0xFFFFF` | 16B | 系统 BIOS 入口地址 | + +0x000 - 0x3ff -> 0x400 + +4B + +0x400 / 4 = 0x100 -> 256 + +0 - 255 + +0 除法异常 0 - 3 + +0x80 * 4, 0x80 * 4 + 3 + +0x80 linux 系统调用,软中断 + + +## 逻辑运算指令 + +- AND - TEST / SUB - CMP +- OR +- NOT +- XOR + +- SHL / SHR +- ROL / ROR +- RCL / RCR + + +## 输入和输出 + +输入输出指令,来控制硬件(外围设备) + +- 显示器 - 显卡 +- 硬盘 +- 键盘 + +端口 / 映射内存, + +寄存器 / D 边沿触发器 + +Intell 0-65535 0x0000 ~ 0xffff + +阴极射线管控制器 + +CRT 地址端口 0x3D4 +CRT 数据端口 0x3D5 + +80 * 25 = 2000 + +16 位 / 8 位 + +16K 字符 + +0 - 1999 + +0x0E - 光标位置高八位 +0x0F - 光标位置第八位 + +```s +in al, dx; dx 端口号 +in ax, dx; ax/al 数 +out dx, al; +out dx, ax; +``` + +ax 16 , al 8 + +## 控制字符样式 + +- ASCII 码 +- 字符样式 + +-- + +- 高四位表示背景色 | K | R | G | B | +- 低四位表示前景色 | I | R | G | B | + +--- + +- K = 0 : 背景不闪烁 +- K = 1 : 背景闪烁 +- I = 0 : 深色字符 +- I = 1 : 浅色字符 + +--- + +| Red | Green | Blue | Color | 说明 | +| --- | ----- | ---- | ------- | --------- | +| 0 | 0 | 0 | Black | 黑色 | +| 0 | 0 | 1 | Blue | 蓝色 | +| 0 | 1 | 0 | Green | 绿色 | +| 0 | 1 | 1 | Cyan | 青色 | +| 1 | 0 | 0 | Red | 红色 | +| 1 | 0 | 1 | Magenta | 洋红 | +| 1 | 1 | 0 | Yellow | 黄色 | +| 1 | 1 | 1 | White | 白色/灰色 | + +## 外中断和时钟 + +- 内中断和异常 +- 输入和输出 + +--- + +CPU ---> 硬件,端口 + +- 键盘 +- 鼠标 + +--- + +- 时钟信号/脉冲 - CPU 的脉搏 +- 时钟中断 - OS 的脉搏 + +--- + +8086 + +- NMI Non Maskable Interrupt / 不可屏蔽中断 +- INTR Interrupt / 可屏蔽中断 + +---- + +8259 - 可编程中断控制器 / PIC Programmable Interrupt Controller + +- 主芯片 - 8 1 +- 从芯片 - 8 +- 级联方式 + + +### 中断向量表 + +| 向量 | 功能 | +| ---- | --------------- | +| 0 | 除法溢出 | +| 1 | 单步 (用于调试) | +| 2 | 非屏蔽中断 NMI | +| 3 | 断点 (用于调试) | +| 4 | 溢出中断 | +| 5 | 打印屏幕 | +| 6-7 | 保留 | +| 8 | 时钟 | +| 9 | 键盘 | +| A | 保留 | +| B | 串行通信COM2 | +| C | 串行通信COM1 | +| D | 保留 | +| E | 软盘控制器 | +| F | 并行打印机 | + +| 端口 | 说明 | 标记 | +| ---- | --------------- | ---------- | +| 0x20 | 主 PIC 命令端口 | PIC_M_CMD | +| 0x21 | 主 PIC 数据端口 | PIC_M_DATA | +| 0xA0 | 从 PIC 命令端口 | PIC_S_CMD | +| 0xA1 | 从 PIC 数据端口 | PIC_S_DATA | + +- ICW1 ~ ICW4 用于初始化 8259 initialization Command Words +- OCW1 ~ OCW3 用于操作 8259 Operation Commands Words + +--- + +- 向 OCW1 写入屏蔽字,打开时钟中断 +- sti 设置 CPU 允许外中断 +- 向 OCW2 写入 0x20, 表示中断处理完毕 + +中断向量表 + +中断函数指针数组 + +- IF / CPU 的外中断开关 +- MASK 中断屏蔽开关 / 8259 总开关 +- 执行中的开关 + +- +- diff --git "a/x86_assembly/docs/\345\206\205\345\255\230\345\270\203\345\261\200.md" "b/x86_assembly/docs/\345\206\205\345\255\230\345\270\203\345\261\200.md" new file mode 100644 index 0000000..602ad78 --- /dev/null +++ "b/x86_assembly/docs/\345\206\205\345\255\230\345\270\203\345\261\200.md" @@ -0,0 +1,16 @@ + +| 起始地址 | 结束地址 | 大小 | 用途 | +| --------- | --------- | -------- | ------------------ | +| `0x000` | `0x3FF` | 1KB | 中断向量表 | +| `0x400` | `0x4FF` | 256B | BIOS 数据区 | +| `0x500` | `0x7BFF` | 29.75 KB | 可用区域 | +| `0x7C00` | `0x7DFF` | 512B | MBR 加载区域 | +| `0x7E00` | `0x9FBFF` | 607.6KB | 可用区域 | +| `0x9FC00` | `0x9FFFF` | 1KB | 扩展 BIOS 数据区 | +| `0xA0000` | `0xAFFFF` | 64KB | 用于彩色显示适配器 | +| `0xB0000` | `0xB7FFF` | 32KB | 用于黑白显示适配器 | +| `0xB8000` | `0xBFFFF` | 32KB | 用于文本显示适配器 | +| `0xC0000` | `0xC7FFF` | 32KB | 显示适配器 BIOS | +| `0xC8000` | `0xEFFFF` | 160KB | 映射内存 | +| `0xF0000` | `0xFFFEF` | 64KB-16B | 系统 BIOS | +| `0xFFFF0` | `0xFFFFF` | 16B | 系统 BIOS 入口地址 | \ No newline at end of file diff --git "a/x86_assembly/docs/\345\217\202\350\200\203\350\265\204\346\226\231.md" "b/x86_assembly/docs/\345\217\202\350\200\203\350\265\204\346\226\231.md" new file mode 100644 index 0000000..ad5ecf7 --- /dev/null +++ "b/x86_assembly/docs/\345\217\202\350\200\203\350\265\204\346\226\231.md" @@ -0,0 +1,94 @@ +# 参考资料 + +参考资料陆续更新中 …… + +## 相关书籍 + +- [王爽 - 汇编语言](https://book.douban.com/subject/3037562/) +- [于渊 - Orange'S:一个操作系统的实现](https://book.douban.com/subject/3735649/) +- [赵炯 - Linux内核完全注释](https://book.douban.com/subject/1231236/) +- [[日] 川合秀实 - 30天自制操作系统](https://book.douban.com/subject/11530329/) +- [李忠 & 王晓波 & 余洁 - X86汇编语言](https://book.douban.com/subject/20492528/) +- [Intel - Intel® 64 and IA-32 Architectures Software Developer's Manual](https://book.douban.com/subject/3990545/) +- [郑钢 - 操作系统真象还原](https://book.douban.com/subject/26745156/) +- [Robert Mecklenburg - Managing Projects With GNU Make](https://book.douban.com/subject/1850994/) +- [Richard Blum - 汇编语言程序设计](https://book.douban.com/subject/1446250/) +- [俞甲子 & 石凡 & 潘爱民 - 程序员的自我修养](https://book.douban.com/subject/3652388/) +- [Paul A. Carter - PC Assembly Language](https://book.douban.com/subject/26892163/) +- [Stephen G. Kochan - Programming in C](https://book.douban.com/subject/2250163/) +- [P. J. Plauger - The Standard C Library](https://book.douban.com/subject/1920997/) +- [Kip R. Irvine - Assembly Language for x86 Processors (7th Edition)](https://book.douban.com/subject/26616933/) + +其他 pdf: + +- [IBM - IBM 5150 Technical Reference 6025005 AUG81]() +- [Intel - Intel 8259a]() +- [Intel - Intel 8253]() +- [TIS Committee - Executable and Linking Format (ELF) Specification](https://refspecs.linuxfoundation.org/elf/elf.pdf) +- [GNU - Using as the GNU Assembler](https://web.eecs.umich.edu/~prabal/teaching/resources/eecs373/Assembler.pdf) +- [Red Hat - Using ld the GNU Linker](https://access.redhat.com/webassets/avalon/d/Red_Hat_Enterprise_Linux-4-Red_Hat_Enterprise_Linux_4_-_Archived_Documents-en-US/files/Red_Hat_Enterprise_Linux-4-Using_ld_the_GNU_Linker-en-US.pdf) +- [GNU - Debugging with GDB](https://sourceware.org/gdb/current/onlinedocs/gdb.pdf) + +## 视频引用 + +- 进入保护模式 + - + - +- 一些补充说明: + - + +--- + +- 结构体 + - +- GCC attribute + - +- GCC 函数属性 + - +- GCC builtin + - +- Using as the GNU Assembler + - + - +- 内联汇编 + - + - + - +- 生成可读汇编的方法 + - + - +- 链接 + - + - + - +- 调试: + - + - +- nasm: + - + - + +--- + +- Executable and Linking Format (ELF) Specification + - + + +- 其他 + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - diff --git "a/x86_assembly/docs/\345\220\257\345\212\250\346\265\201\347\250\213.md" "b/x86_assembly/docs/\345\220\257\345\212\250\346\265\201\347\250\213.md" new file mode 100644 index 0000000..32ac893 --- /dev/null +++ "b/x86_assembly/docs/\345\220\257\345\212\250\346\265\201\347\250\213.md" @@ -0,0 +1,12 @@ +# PC 启动流程 + +```mermaid +flowchart TD +T1(CPU 加电自检) --> T2(进入 BIOS) --> T3(主引导扇区 boot 0x7c00) --> T4(读取 loader) --> T5(进入 loader) --> T6(检测内存) --> T7(准备保护模式) --> T8(进入保护模式) --> T9(内存映射) --> T10(加载内核) +``` + +主引导扇区(MBR Main Boot Record)只有 512 个字节: + +- 446 可用 +- 64 硬盘分区表 +- 2 0x55aa diff --git a/x86_assembly/makefile b/x86_assembly/makefile new file mode 100644 index 0000000..0c00e0b --- /dev/null +++ b/x86_assembly/makefile @@ -0,0 +1,49 @@ + +CFLAGS:= -m32 \ + -O0 \ + -static \ + -fno-asynchronous-unwind-tables \ + -fno-pic \ + -fno-pie \ + -mpreferred-stack-boundary=2 \ + -fno-stack-protector \ + -fno-builtin \ + -fomit-frame-pointer \ + -nostdlib \ + -nodefaultlibs \ + -nostdinc \ + -nostartfiles \ + +build/%.bin: src/%.asm + nasm $< -o $@ + +build/%.o: src/%.asm + nasm -f elf32 $< -o $@ + +build/%.o: src/%.c + gcc $(CFLAGS) -c $< -o $@ + +ENTRYPOINT:= 0x00011000 + +build/kernel.bin: build/start.o build/main.o + ld -m elf_i386 -static $^ -o $@ -Ttext $(ENTRYPOINT) + +build/master.img: build/boot.bin build/loader.bin build/kernel.bin +ifeq ("$(wildcard build/master.img)", "") + bximage -q -hd=16 -mode=create -sectsize=512 -imgmode=flat $@ +endif + dd if=build/boot.bin of=$@ bs=512 count=1 conv=notrunc + dd if=build/loader.bin of=$@ bs=512 count=4 seek=2 conv=notrunc + dd if=build/kernel.bin of=$@ bs=512 count=100 seek=10 conv=notrunc + +.PHONY:bochs +bochs: build/master.img + rm -rf build/bx_enh_dbg.ini + cd build && bochs -q -unlock + +.PHONY:clean +clean: + rm -rf build/bx_enh_dbg.ini + rm -rf build/master.img + rm -rf build/*.bin + rm -rf build/*.o diff --git a/x86_assembly/src/boot.asm b/x86_assembly/src/boot.asm new file mode 100644 index 0000000..87068b5 --- /dev/null +++ b/x86_assembly/src/boot.asm @@ -0,0 +1,108 @@ +[org 0x7c00] + +mov ax, 3 +int 0x10 ; 将显示模式设置成文本模式 + +mov ax, 0 +mov ds, ax +mov es, ax +mov ss, ax +mov sp, 0x7c00 ; 初始化堆栈 + +; xchg bx, bx ; bochs 断点 + +mov edi, 0x1000 +mov ecx, 2 +mov bl, 4 +call read_disk + +; xchg bx, bx; + +jmp 0:0x1000; 跳转到 loader + +; 0 -> 0x1000 + +read_disk: + ; 读取硬盘 + ; edi - 存储内存位置 + ; ecx - 存储起始的扇区位置 + ; bl - 存储扇区数量 + pushad; ax, cx, dx, bx, sp, bp, si, di + ; pushad; ax, cx, dx, bx, sp, bp, si, di + + mov dx, 0x1f2 + mov al, bl + out dx, al; 设置扇区数量 + + mov al, cl + inc dx; 0x1f3 + out dx, al; 起始扇区位置低八位 + + shr ecx, 8 + mov al, cl + inc dx; 0x1f4 + out dx, al; 起始扇区位置中八位 + + shr ecx, 8 + mov al, cl + inc dx; 0x1f5 + out dx, al; 起始扇区位置高八位 + + shr ecx, 8 + and cl, 0b1111 + + inc dx; 0x1f6 + mov al, 0b1110_0000 + or al, cl + out dx, al + + inc dx; 0x1f7 + mov al, 0x20; 读硬盘 + out dx, al + + xor ecx, ecx + mov cl, bl + +.read: + push cx + call .waits + call .reads + pop cx + loop .read + + popad + ; popa + + ret + + +.waits: + mov dx, 0x1f7 + .check: + nop + nop + nop ; 一点延迟 + + in al, dx + and al, 0b1000_1000 + cmp al, 0b0000_1000 + jnz .check + ret + +.reads: + mov dx, 0x1f0 + mov cx, 256; 一个扇区 256 个字 + .readw: + nop + nop + nop + + in ax, dx + mov [edi], ax + add edi, 2 + + loop .readw + ret + +times 510 - ($ - $$) db 0 +db 0x55, 0xaa diff --git a/x86_assembly/src/loader.asm b/x86_assembly/src/loader.asm new file mode 100644 index 0000000..ad08b6a --- /dev/null +++ b/x86_assembly/src/loader.asm @@ -0,0 +1,268 @@ +[org 0x1000] + +; xchg bx, bx + +check_memory: + mov ax, 0 + mov es, ax + xor ebx, ebx + mov edx, 0x534d4150 + mov di, ards_buffer + +.next: + mov eax, 0xE820 + mov ecx, 20 + int 0x15 + + jc .error + + add di, cx + inc word [ards_count] + cmp ebx, 0 + jnz .next + + jmp prepare_protect_mode + +; xchg bx, bx + +; mov cx, [ards_count] +; mov si, 0 +; .show: +; mov eax, [si + ards_buffer] +; mov ebx, [si + ards_buffer + 8] +; mov edx, [si + ards_buffer + 16] +; add si, 20 +; xchg bx, bx +; loop .show + +.error: + mov ax, 0xb800 + mov es, ax + mov byte [es:0], 'E' + jmp $ + + +prepare_protect_mode: + ; xchg bx, bx + + cli ; 关闭中断 + + ; 打开 A20 线 + in al, 0x92 + or al, 0b10 + out 0x92, al + + lgdt [gdt_ptr]; 加载 gdt + + mov eax, cr0; 启动保护模式 + or eax, 1 + mov cr0, eax + + jmp dword code_selector:protect_enable + + ud2; 出错 + +[bits 32] +protect_enable: + + mov ax, data_selector + mov ds, ax + mov es, ax + mov ss, ax + mov fs, ax + mov gs, ax; 初始化数据段 + + mov esp, 0x10000 + + call setup_page + + xchg bx, bx + + call load_kernel + + jmp code_selector: 0x11000 + + jmp $ + +load_kernel: + mov edi, 0x10000 + mov ecx, 10 + mov bl, 100 + call read_disk + ret + +PDE equ 0x2000 +PTE equ 0x3000 +ATTR equ 0b11 + +setup_page: + mov eax, PDE + call .clear_page + mov eax, PTE + call .clear_page + + ; 前面的 1M 内 前面的 1M + ; 前面的 1M 映射到 0xC0000000 ~ 0xC0100000 + mov eax, PTE + or eax, ATTR + mov [PDE], eax; + ;0b_00000_00000_00000_00000_00000_00000_00 + mov [PDE + 0x300 * 4], eax; + ;0b_11000_00000_00000_00000_00000_00000_00 + + mov eax, PDE + or eax, ATTR + mov [PDE + 0x3ff * 4], eax; 吧最后一个页表指向了页目录 + + mov ebx, PTE + mov ecx, (0x100000 / 0x1000); 256 + mov esi, 0 + ; xchg bx, bx + +.next_page: + mov eax, esi + shl eax, 12 + or eax, ATTR + + mov [ebx + esi * 4], eax + inc esi + loop .next_page + + ; xchg bx, bx + mov eax, PDE + mov cr3, eax + + mov eax, cr0 + or eax, 0b1000_0000_0000_0000_0000_0000_0000_0000 + mov cr0, eax + + ret + +.clear_page: + ; 清空一个内存页,地址参数存在 eax 中 + mov ecx, 0x1000 + mov esi, 0 +.set: + mov byte [eax + esi], 0 + inc esi + loop .set + ret + +read_disk: + ; 读取硬盘 + ; edi - 存储内存位置 + ; ecx - 存储起始的扇区位置 + ; bl - 存储扇区数量 + pushad; ax, cx, dx, bx, sp, bp, si, di + ; pushad; ax, cx, dx, bx, sp, bp, si, di + + mov dx, 0x1f2 + mov al, bl + out dx, al; 设置扇区数量 + + mov al, cl + inc dx; 0x1f3 + out dx, al; 起始扇区位置低八位 + + shr ecx, 8 + mov al, cl + inc dx; 0x1f4 + out dx, al; 起始扇区位置中八位 + + shr ecx, 8 + mov al, cl + inc dx; 0x1f5 + out dx, al; 起始扇区位置高八位 + + shr ecx, 8 + and cl, 0b1111 + + inc dx; 0x1f6 + mov al, 0b1110_0000 + or al, cl + out dx, al + + inc dx; 0x1f7 + mov al, 0x20; 读硬盘 + out dx, al + + xor ecx, ecx + mov cl, bl + +.read: + push cx + call .waits + call .reads + pop cx + loop .read + + popad + ; popa + + ret + + +.waits: + mov dx, 0x1f7 + .check: + nop + nop + nop ; 一点延迟 + + in al, dx + and al, 0b1000_1000 + cmp al, 0b0000_1000 + jnz .check + ret + +.reads: + mov dx, 0x1f0 + mov cx, 256; 一个扇区 256 个字 + .readw: + nop + nop + nop + + in ax, dx + mov [edi], ax + add edi, 2 + + loop .readw + ret + +code_selector equ (1 << 3) +data_selector equ (2 << 3) +test_selector equ (3 << 3) + +gdt_ptr: + dw (gdt_end - gdt_base - 1) + dd gdt_base + +gdt_base: + dd 0, 0 +gdt_code: + dw 0xffff; + dw 0 + db 0; + db 0b1001_1110 + db 0b1100_1111 + db 0 +gdt_data: + dw 0xffff; + dw 0 + db 0 + db 0b1001_0010 + db 0b1100_1111 + db 0 +gdt_test: + dw 0xfff + dw 0x0000 + db 0x1 + db 0b1001_0010 ;0x92 + db 0b0100_0000 ; 0x40 + db 0x0 +gdt_end: + +ards_count: + dw 0 +ards_buffer: diff --git a/x86_assembly/src/main.c b/x86_assembly/src/main.c new file mode 100644 index 0000000..17f8ad8 --- /dev/null +++ b/x86_assembly/src/main.c @@ -0,0 +1,17 @@ + +char message[] = "hello kernel!!!"; + +int main() +{ + char *video = (char *)0xb8000; + + for (int i = 0; i < sizeof(message); i++) + { + *video = message[i]; + video++; + *video = 0b00100101; + video++; + } + + return 0; +} diff --git a/x86_assembly/src/start.asm b/x86_assembly/src/start.asm new file mode 100644 index 0000000..2784e14 --- /dev/null +++ b/x86_assembly/src/start.asm @@ -0,0 +1,12 @@ +[bits 32] + +extern main + +section .text +global _start +_start: + xchg bx, bx; + mov byte [0xb8000], 'S'; + xchg bx, bx; + call main + jmp $ diff --git a/x86_assembly/tests/addr.asm b/x86_assembly/tests/addr.asm new file mode 100644 index 0000000..12eabb8 --- /dev/null +++ b/x86_assembly/tests/addr.asm @@ -0,0 +1,31 @@ +offset equ 0x0000 +data equ 0x55aa + +mov ax, 0x1000 +mov ds, ax + +mov al, 0x10 +mov ah, 0x10 +mov ax, data + +mov ax, [offset] ; 0x1000 * 0x10 + 0 = 0x100000 +mov [offset], ax; + +; dd 0xffeeffee + +mov byte [offset], 0x10 +mov word [offset], 0x10 +mov dword [offset], 0x10 + +; bx bp si di + +mov ax, [bx]; [ds * 16 + bx] +mov ax, [bp]; [ss * 16 + bp] +mov ax, [si]; [ds * 16 + bp] +mov ax, [di]; [ds * 16 + bp] + +mov ax, [bx + si + 0x100] ; ds +mov ax, [bp + si + 0x100] ; ss +mov ax, [bp + di + 0x100] + + diff --git a/x86_assembly/tests/att.s b/x86_assembly/tests/att.s new file mode 100644 index 0000000..0c395bf --- /dev/null +++ b/x86_assembly/tests/att.s @@ -0,0 +1,30 @@ + +.section .text +.globl main +main: + # 内联汇编 + + movl $4, %eax # write + movl $1, %ebx # stdout + movl $message, %ecx # buffer + movb $'A', message + movb $'B', 1(%ecx) + movb $'C', (%ecx, %ebx, 2) + movb $'D', message - 1(, %ebx, 4) + movb $'E', message(, %ebx, 4) + + movl $(message_end - message), %edx # length + int $0x80 + + movl $1, %eax # exit + movl $0, %ebx # status + int $0x80 + +.section .data +message: + .asciz "hello world!!!\n" +message_end: + + +.section .bss + .lcomm buffer 256 diff --git a/x86_assembly/tests/descriptor.c b/x86_assembly/tests/descriptor.c new file mode 100644 index 0000000..e9a3ae2 --- /dev/null +++ b/x86_assembly/tests/descriptor.c @@ -0,0 +1,67 @@ +#include + +typedef struct descriptor /* 共 8 个字节 */ +{ + unsigned short limit_low; // 段界限 0 ~ 15 位 + unsigned int base_low : 24; // 基地址 0 ~ 23 位 16M + unsigned char type : 4; // 段类型 + unsigned char segment : 1; // 1 表示代码段或数据段,0 表示系统段 + unsigned char DPL : 2; // Descriptor Privilege Level 描述符特权等级 0 ~ 3 + unsigned char present : 1; // 存在位,1 在内存中,0 在磁盘上 + unsigned char limit_high : 4; // 段界限 16 ~ 19; + unsigned char available : 1; // 该安排的都安排了,送给操作系统吧 + unsigned char long_mode : 1; // 64 位扩展标志 + unsigned char big : 1; // 32 位 还是 16 位; + unsigned char granularity : 1; // 粒度 4KB 或 1B + unsigned char base_high; // 基地址 24 ~ 31 位 +} __attribute__((packed)) descriptor; + +void make_descriptor(descriptor *dest, unsigned int base, unsigned int limit) +{ + dest->base_low = base & 0xffffff; + dest->base_high = (base >> 24) & 0xff; + + dest->limit_low = limit & 0xffff; + dest->limit_high = (limit >> 16) & 0xf; +} + +int main(int argc, char const *argv[]) +{ + descriptor dest; + make_descriptor(&dest, 0x10000, 0xfff); + + dest.granularity = 0; // 字节 + dest.big = 1; // 32 位 + dest.long_mode = 0; // 不是 64 位 + dest.present = 1; // 在内存中 + dest.DPL = 0; // 最高权限 + dest.segment = 1; // 数据段 + dest.available = 0; // 0 + dest.type = 0b0010; // 可写数据段向上扩展 + + char *ptr = (char *)&dest; + + unsigned short value16 = *(short *)ptr; + printf("dw 0x%x\n", value16); + + ptr += 2; + value16 = *(short *)ptr; + printf("dw 0x%x\n", value16); + + ptr += 2; + unsigned char value8 = *(char *)ptr; + printf("db 0x%x\n", value8); + + ptr++; + value8 = *(char *)ptr; + printf("db 0x%x\n", value8); + + ptr++; + value8 = *(char *)ptr; + printf("db 0x%x\n", value8); + + ptr++; + value8 = *(char *)ptr; + printf("db 0x%x\n", value8); + return 0; +} diff --git a/x86_assembly/tests/elf.asm b/x86_assembly/tests/elf.asm new file mode 100644 index 0000000..5ff6dfb --- /dev/null +++ b/x86_assembly/tests/elf.asm @@ -0,0 +1,25 @@ +[bits 32] + +section .text + +global _start +_start: + mov eax, 4; write + mov ebx, 1; stdout + mov ecx, message; buffer + mov edx, message_end - message + int 0x80 + + mov eax, 1; exit + mov ebx, 0; status + int 0x80 + +section .data + message db "hello world!!!", 10, 13, 0 + message_end: + +section .bss + resb 0x100 ; 预留 0x100 字节的空间 + ; resw 0x100 ; 预留 0x100 字的空间 + ; resd 0x100 ; 预留 0x100 双字的空间 + ; resq 0x100 ; 预留 0x100 四字的空间 diff --git a/x86_assembly/tests/hello.asm b/x86_assembly/tests/hello.asm new file mode 100644 index 0000000..e7a46ec --- /dev/null +++ b/x86_assembly/tests/hello.asm @@ -0,0 +1,36 @@ +[bits 32] + +; extern printf +; extern exit + +; section .text +; global main +; main: +; push message +; call printf +; add esp, 4 + +; push 0 +; call exit + +; section .data +; message db "hello world!!!", 10, 13, 0 +; message_end: + +section .text +global main +main: + + mov eax, 4; write + mov ebx, 1; stdout + mov ecx, message; buffer + mov edx, message_end - message + int 0x80 + + mov eax, 1; exit + mov ebx, 0; status + int 0x80 + +section .data + message db "hello world!!!", 10, 13, 0 + message_end: diff --git a/x86_assembly/tests/jump.asm b/x86_assembly/tests/jump.asm new file mode 100644 index 0000000..153611c --- /dev/null +++ b/x86_assembly/tests/jump.asm @@ -0,0 +1,2 @@ +[bits 16] +jmp dword 8:0x1010 \ No newline at end of file diff --git a/x86_assembly/tests/protect.asm b/x86_assembly/tests/protect.asm new file mode 100644 index 0000000..2617f87 --- /dev/null +++ b/x86_assembly/tests/protect.asm @@ -0,0 +1,16 @@ +[bits 32] + +extern exit + +section .text +global main +main: + ; mov eax, cr0; 寄存器的保护 + + ; in al, 0x92; + + push 0 + call exit + + + diff --git a/x86_assembly/tests/type.asm b/x86_assembly/tests/type.asm new file mode 100644 index 0000000..5d98326 --- /dev/null +++ b/x86_assembly/tests/type.asm @@ -0,0 +1,9 @@ +db 100; define byte +dw 0xaa55; define word +dd 0x12345678; define doubleword + +dw 55aah; +db 1111_0000b +db 0b0000_1111 + +db "hello world!!!", 0, 12, 123