Browse Source

文章适配

master
lniwn 7 years ago
parent
commit
2faeb2ca9b
  1. 8
      archetypes/posts.md
  2. 15
      config.toml
  3. 16
      content/about.md
  4. BIN
      content/posts/2017/CMake学习笔记/CMake-Projects.png
  5. BIN
      content/posts/2017/CMake学习笔记/VS-to-CMake-Mapping.png
  6. 4
      content/posts/2017/CMake学习笔记/index.md
  7. 9
      content/posts/2017/CMake项目添加预编译头.md
  8. 0
      content/posts/2017/Cef-Bug-Fix-List.md
  9. 0
      content/posts/2017/一句话Windows.md
  10. 0
      content/posts/2017/为Hexo博客Next主题添加Schnack评论.md
  11. 16
      content/posts/2017/为Hexo博客Next主题添加Wildfire评论系统.md
  12. 1
      content/posts/2017/在vps上搭建hexo.md
  13. 0
      content/posts/2017/注释大全.md
  14. 0
      content/posts/2018/Python模块timezone学习笔记.md
  15. 0
      content/posts/2018/SQLAlchemy学习笔记.md
  16. 4
      content/posts/2018/Vim快捷键备忘录/index.md
  17. BIN
      content/posts/2018/Vim快捷键备忘录/morden1.png
  18. BIN
      content/posts/2018/Vim快捷键备忘录/text1.png
  19. 572
      content/posts/2018/Win32汇编学习.md
  20. 0
      content/posts/2018/Win32汇编学习/index.md
  21. BIN
      content/posts/2018/Win32汇编学习/stack-convention.png
  22. BIN
      content/posts/2018/Win32汇编学习/stackframe.png
  23. BIN
      content/posts/2018/Win32汇编学习/x86-registers.png
  24. 3
      content/posts/2018/office2016激活步骤.md
  25. 0
      content/posts/2018/为Ubuntu启用Swap分区.md
  26. BIN
      content/posts/2018/加快Visual-Studio编译速度/after.png
  27. BIN
      content/posts/2018/加快Visual-Studio编译速度/before.png
  28. 4
      content/posts/2018/加快Visual-Studio编译速度/index.md
  29. 0
      content/posts/2018/动态获取当前模块的HMODULE-HINSTANCE值.md
  30. BIN
      content/posts/2018/流畅的Python学习笔记/frame13-1.png
  31. BIN
      content/posts/2018/流畅的Python学习笔记/frame7-1.png
  32. 4
      content/posts/2018/流畅的Python学习笔记/index.md
  33. 1
      content/posts/2018/解决chromium警告C4819.md
  34. 18
      content/posts/2019/hugo部署笔记.md
  35. 8
      content/posts/others/_index.md

8
archetypes/posts.md

@ -0,0 +1,8 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
toc: true
images:
tags: [untagged]
---

15
config.toml

@ -13,11 +13,14 @@ enableEmoji = true # Shorthand emojis in content files - https://gohugo.io/func
# googleAnalytics = "UA-123-45" # googleAnalytics = "UA-123-45"
# disqusShortname = "yourdiscussshortname" # disqusShortname = "yourdiscussshortname"
[permalinks]
# posts = "/:year/:month/:title/"
[author] [author]
name = "lniwn" name = "lniwn"
[blackfriday] [blackfriday]
# hrefTargetBlank = true hrefTargetBlank = true
# noreferrerLinks = true # noreferrerLinks = true
# nofollowLinks = true # nofollowLinks = true
@ -30,7 +33,7 @@ enableEmoji = true # Shorthand emojis in content files - https://gohugo.io/func
dateform = "Jan 2, 2006" dateform = "Jan 2, 2006"
dateformShort = "Jan 2" dateformShort = "Jan 2"
dateformNum = "2006-01-02" dateformNum = "2006-01-02"
dateformNumTime = "2006-01-02 15:04 -0700" dateformNumTime = "2006-01-02 15:04"
# Metadata mostly used in document's head # Metadata mostly used in document's head
# description = "" # description = ""
@ -69,21 +72,21 @@ enableEmoji = true # Shorthand emojis in content files - https://gohugo.io/func
[menu] [menu]
[[menu.main]] [[menu.main]]
name = "Posts" name = "文章"
url = "posts/" url = "posts/"
weight = 1 weight = 1
[[menu.main]] [[menu.main]]
name = "Categories" name = "分类"
url = "categories/" url = "categories/"
weight = 2 weight = 2
[[menu.main]] [[menu.main]]
name = "Tags" name = "标签"
url = "tags/" url = "tags/"
weight = 3 weight = 3
[[menu.main]] [[menu.main]]
name = "About" name = "关于"
url = "about/" url = "about/"
weight = 4 weight = 4

16
content/about.md

@ -1,17 +1,7 @@
+++ +++
title = "About Hugo" title = "关于"
date = "2014-04-09" date = "2019-07-26"
+++ +++
Hugo is the **world’s fastest framework for building websites**. It is written in Go. 此处应该有文字
It makes use of a variety of open source projects including:
* https://github.com/russross/blackfriday
* https://github.com/alecthomas/chroma
* https://github.com/muesli/smartcrop
* https://github.com/spf13/cobra
* https://github.com/spf13/viper
Learn more and contribute on [GitHub](https://github.com/gohugoio).

BIN
content/posts/2017/CMake学习笔记/CMake-Projects.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
content/posts/2017/CMake学习笔记/VS-to-CMake-Mapping.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

4
content/posts/CMake学习笔记.md → content/posts/2017/CMake学习笔记/index.md

@ -51,8 +51,8 @@ add_executable(Demo ${DIR_SRCS})
### 编译选项命令 ### 编译选项命令
- Visual Studio to CMake Mapping - Visual Studio to CMake Mapping
{% asset_img VS-to-CMake-Mapping.png VS-to-CMake-Mapping %} ![VS-to-CMake-Mapping](VS-to-CMake-Mapping.png)
{% asset_img CMake-Projects.png CMake-Projects %} ![CMake-Projects](CMake-Projects.png)
> ZERO_CHECK will rerun cmake. You can/should execute this after changing something on your CMake files. > ZERO_CHECK will rerun cmake. You can/should execute this after changing something on your CMake files.
> ALL_BUILD is simply a target which builds all and everything project in the active solution, I guess one can compare it to "make all". > ALL_BUILD is simply a target which builds all and everything project in the active solution, I guess one can compare it to "make all".
> 可以通过`set(CMAKE_SUPPRESS_REGENERATION true)`不生成`ZERO_CHECK`工程。 > 可以通过`set(CMAKE_SUPPRESS_REGENERATION true)`不生成`ZERO_CHECK`工程。

9
content/posts/CMake项目添加预编译头.md → content/posts/2017/CMake项目添加预编译头.md

@ -2,7 +2,6 @@
title: CMake项目添加预编译头 title: CMake项目添加预编译头
date: 2017-12-28 11:46:13 +08:00 date: 2017-12-28 11:46:13 +08:00
tags: [cmake, visual studio] tags: [cmake, visual studio]
images: ["apple-touch-icon.png"]
categories: cmake categories: cmake
--- ---
@ -61,17 +60,13 @@ use_precompiled_header(${PROJECT_NAME}
在`PrecompiledHeader.cmake`文件中,最开始使用了如下的代码 在`PrecompiledHeader.cmake`文件中,最开始使用了如下的代码
{% note danger %} ```cmake
{% codeblock lang:cmake %}
if (MSVC AND NOT NMAKE AND NOT OGRE_UNITY_BUILD) if (MSVC AND NOT NMAKE AND NOT OGRE_UNITY_BUILD)
set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS /Yu"${HEADER}") set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS /Yu"${HEADER}")
set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS /FI"${HEADER}") set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS /FI"${HEADER}")
set_source_files_properties(${SRC_FILE} set_source_files_properties(${SRC_FILE}
PPROPERTIES COMPILE_FLAGS /Yc"${HEADER}" PPROPERTIES COMPILE_FLAGS /Yc"${HEADER}"
) )
{% endcodeblock %} ```
{% endnote %}
可是发现永远只有/FI生效,后来查找了大量资料,替换为了`set_property APPEND`的形式,才最终解决。 可是发现永远只有/FI生效,后来查找了大量资料,替换为了`set_property APPEND`的形式,才最终解决。

0
content/posts/Cef-Bug-Fix-List.md → content/posts/2017/Cef-Bug-Fix-List.md

0
content/posts/一句话Windows.md → content/posts/2017/一句话Windows.md

0
content/posts/为Hexo博客Next主题添加Schnack评论.md → content/posts/2017/为Hexo博客Next主题添加Schnack评论.md

16
content/posts/为Hexo博客Next主题添加Wildfire评论系统.md → content/posts/2017/为Hexo博客Next主题添加Wildfire评论系统.md

@ -11,11 +11,11 @@ categories: vps
## Hexo配置步骤 ## Hexo配置步骤
{% note primary %} Step 1 {% endnote %} ### Step 1
关于wildfire的设置,请直接参考{% link 官方帮助文档 https://wildfire.js.org/#/zh-cn/usage?id=%e4%bd%bf%e7%94%a8%e8%af%b4%e6%98%8e %} 关于wildfire的设置,请直接参考[官方帮助文档](https://wildfire.js.org/#/zh-cn/usage?id=%e4%bd%bf%e7%94%a8%e8%af%b4%e6%98%8e)
{% note primary %} Step 2 {% endnote %} ### Step 2
在`%BLOG_PATH%\themes\next\layout\_third-party\comments`路径下创建`wildfire.swig`文件 在`%BLOG_PATH%\themes\next\layout\_third-party\comments`路径下创建`wildfire.swig`文件
@ -44,14 +44,14 @@ categories: vps
{% endif %} {% endif %}
``` ```
{% note primary %} Step 3 {% endnote %} ### Step 3
{% quote %}%BLOG_PATH%\themes\next\layout\_third-party\comments\index.swig{% endquote %}文件中添加wildfire.swig的引用: `%BLOG_PATH%\themes\next\layout\_third-party\comments\index.swig`文件中添加wildfire.swig的引用:
{% code lang:swig %} ```swig
{% raw %}{% include 'wildfire.swig' %}{% endraw %} {% raw %}{% include 'wildfire.swig' %}{% endraw %}
{% endcode%} ```
{% note primary %} Step 4 {% endnote %} ### Step 4
在`%BLOG_PATH%\themes\next\layout\_partials\comments.swig`文件中,添加一个elseif代码块: 在`%BLOG_PATH%\themes\next\layout\_partials\comments.swig`文件中,添加一个elseif代码块:

1
content/posts/在vps上搭建hexo.md → content/posts/2017/在vps上搭建hexo.md

@ -29,7 +29,6 @@ cp -Rf /home/lniwnxxx/hexo/public/* /var/www/oaoa.me/
``` ```
这样可以在任何地方编写md文件,写完之后通过git提交即可看到自动部署的信息 这样可以在任何地方编写md文件,写完之后通过git提交即可看到自动部署的信息
{% asset_img TortoiseGit-message.png TortoiseGit打印的远程部署信息 %}
由于我创建了一个git用户,仅用于git相关操作,而我的登陆用户是lniwn,部署时经常会遇到权限问题,所以需要进行一些权限分配: 由于我创建了一个git用户,仅用于git相关操作,而我的登陆用户是lniwn,部署时经常会遇到权限问题,所以需要进行一些权限分配:

0
content/posts/注释大全.md → content/posts/2017/注释大全.md

0
content/posts/Python模块timezone学习笔记.md → content/posts/2018/Python模块timezone学习笔记.md

0
content/posts/SQLAlchemy学习笔记.md → content/posts/2018/SQLAlchemy学习笔记.md

4
content/posts/Vim快捷键备忘录.md → content/posts/2018/Vim快捷键备忘录/index.md

@ -131,5 +131,5 @@ Vim快捷键查询。
## 在线文档 ## 在线文档
- [VIM QUICK REFERENCE CARD](http://tnerual.eriogerg.free.fr/vimqrc.pdf) - [VIM QUICK REFERENCE CARD](http://tnerual.eriogerg.free.fr/vimqrc.pdf)
- {% asset_img morden1.png 增强版 %} - ![增强版](morden1.png)
- {% asset_img text1.png 文字版 %} - ![文字版](text1.png)

BIN
content/posts/2018/Vim快捷键备忘录/morden1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 KiB

BIN
content/posts/2018/Vim快捷键备忘录/text1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

572
content/posts/2018/Win32汇编学习.md

@ -0,0 +1,572 @@
---
title: Win32汇编学习
date: 2018-02-12 17:48:00
tags: [win32, 汇编]
categories: windows
---
本文记录了C函数调用过程,以及常用的汇编函数指令集。
<!--more-->
## 函数调用过程
栈帧,即stack frame,其本质就是一种栈,只是这种栈专门用于保存函数调用过程中的各种信息,栈帧有栈顶(TOS)和栈底之分,其中栈顶的地址最低,栈底的地址最高,增长方向为高地址向低地址方向。在x86-32bit中,用esp(extended stack pointer)一直指向栈顶,ebp(extended base pointer)指向栈底。
![栈帧方向](stackframe.png)
一般来说,ebp和esp之间的区域叫做栈帧,每调用一个函数,就会生成一个新的栈帧。在函数调用过程中,我们将调用函数称为“调用者(caller)”,将被调用的函数称为“被调用者(callee)”。
函数调用过程如下:
```asm
push ebp ; 保存ebp的值
mov ebp,esp ; 将esp的值赋给ebp,使新的ebp指向栈顶
sub esp,0d8h ; 分配额外的空间给局部变量,对于大内存,使用call __alloca_probe (010FD4EAh) 的方式来分配
```
windows平台,返回值保存在eax中。
## x86汇编指令
### 寄存器
![x86寄存器](x86-registers.png)
X86处理器中有8个32位的通用寄存器。由于历史的原因,EAX通常用于计算,ECX通常用于循环变量计数。ESP和EBP有专门用途,ESP指示栈指针(用于指示栈顶位置),而EBP则是基址指针(用于指示子程序或函数调用的基址指针)。如图中所示,EAX、EBX、ECX和EDX的前两个高位字节和后两个低位字节可以独立使用,其中两位低字节又被独立分为H和L部分,这样做的原因主要是考虑兼容16位的程序,具体兼容匹配细节请查阅相关文献。
应用寄存器时,其名称大小写是不敏感的,如EAX和eax没有区别。
### 内存和寻址模式
#### 声明静态数据区
可以在X86汇编语言中用汇编指令.DATA声明静态数据区(类似于全局变量),数据以单字节、双字节、或双字(4字节)的方式存放,分别用DB,DW, DD指令表示声明内存的长度。在汇编语言中,相邻定义的标签在内存中是连续存放的。
| .DATA | | |
| ----- | -------- | ------------------------------------- |
| var | DB 64 | ;声明一个字节,并将数值64放入此字节中 |
| var2 | DB ? | ; 声明一个未初始化的字节. |
| | DB 10 | ; 声明一个没有label的字节,其值为10. |
| X | DW ? | ; 声明一个双字节,未初始化. |
| Y | DD 30000 | ; 声明一个4字节,其值为30000. |
还可以声明连续的数据和数组,声明数组时使用DUP关键字。
| .DATA | | |
| ----- | ------------- | ------------------------------------------------------------ |
| Z | DD 1, 2, 3 | ; Declare three 4-byte values, initialized to 1, 2, and 3. The value of location Z + 8 will be 3. |
| bytes | DB 10 DUP(?) | ; Declare 10 uninitialized bytes starting at location *bytes*. |
| arr | DD 100 DUP(0) | ; Declare 100 4-byte words starting at location arr, all initialized to 0 |
| str | DB 'hello',0 | ; Declare 6 bytes starting at the address str, initialized to the ASCII character values for hello and the null (0) byte. |
#### 寻址模式
现代X86处理器具有232字节的寻址空间。在上面的例子中,我们用标签(label)表示内存区域,这些标签在实际汇编时,均被32位的实际地址代替。除了支持这种直接的内存区域描述,X86还提供了一种灵活的内存寻址方式,即利用最多两个32位的寄存器和一个32位的有符号常数相加计算一个内存地址,其中一个寄存器可以左移1、2或3位以表述更大的空间。下面例子是汇编程序中常见的方式。
| 指令 | 说明 |
| -------------------- | ----------------------------------------------- |
| mov eax, [ebx] | ; 将ebx值指示的内存地址中的4个字节传送到eax中 |
| mov [var], ebx | ; 将ebx的内容传送到var的值指示的内存地址中. |
| mov eax, [esi-4] | ; 将esi-4值指示的内存地址中的4个字节传送到eax中 |
| mov [esi+eax], cl | ; 将cl的值传送到esi+eax的值指示的内存地址中 |
| mov edx, [esi+4*ebx] | ; 将esi+4*ebx值指示的内存中的4个字节传送到edx |
#### 长度规定
在声明内存大小时,在汇编语言中,一般用DB,DW,DD均可声明的内存空间大小,这种现实声明能够很好地指导汇编器分配内存空间,但是,对于`mov [ebx], 2`,如果没有特殊的标识,则不确定常数2是单字节、双字节,还是双字。对于这种情况,X86提供了三个指示规则标记,分别为`BYTE PTR`, `WORD PTR`, and `DWORD PTR`,如上面例子写成:`mov BYTE PTR [ebx], 2`, `mov WORD PTR [ebx], 2``mov DWORD PTR [ebx], 2`,则意思非常清晰。
### 汇编指令
汇编指令通常可以分为数据传送指令、逻辑计算指令和控制流指令。本节将讲述其中最重要的指令,以下标记分别表示寄存器、内存和常数。
| 标识 | 描述 |
| ------- | --------------------------------------------------------- |
| <reg32> | 32位寄存器 (EAX, EBX, ECX, EDX, ESI, EDI, ESP, or EBP) |
| <reg16> | 16位寄存器 (AX, BX, CX, or DX) |
| <reg8> | 8位寄存器(AH, BH, CH, DH, AL, BL, CL, or DL) |
| <reg> | 任何寄存器 |
| <mem> | 内存地址 (e.g., [eax], [var + 4], or dword ptr [eax+ebx]) |
| <con32> | 32为常数 |
| <con16> | 16位常数 |
| <con8> | 8位常数 |
| <con> | 任何8位、16位或32位常数 |
#### 数据传送指令
- **mov** — Move (Opcodes: 88, 89, 8A, 8B, 8C, 8E, ...)
mov指令将第二个操作数(可以是寄存器的内容、内存中的内容或值)复制到第一个操作数(寄存器或内存)。mov不能用于直接从内存复制到内存,其语法如下所示:
``` asm
mov <reg>,<reg>
mov <reg>,<mem>
mov <mem>,<reg>
mov <reg>,<const>
mov <mem>,<const>
```
*Examples*
`mov eax, ebx — 将ebx的值拷贝到eax`
`mov byte ptr [var], 5 — 将5保存找var指示内存中的一个字节中`
- **push**— Push stack (Opcodes: FF, 89, 8A, 8B, 8C, 8E, ...)
push指令将操作数压入内存的栈中,栈是程序设计中一种非常重要的数据结构,其主要用于函数调用过程中,其中ESP只是栈顶。在压栈前,首先将ESP值减4(X86栈增长方向与内存地址编号增长方向相反),然后将操作数内容压入ESP指示的位置。其语法如下所示:
```asm
push <reg32>
push <mem>
push <con32>
```
*Examples*
`push eax — 将eax内容压栈`
`push [var] — 将var指示的4直接内容压栈`
- **pop**— Pop stack
pop指令与push指令相反,它执行的是出栈的工作。它首先将ESP指示的地址中的内容出栈,然后将ESP值加4. 其语法如下所示:
```asm
pop <reg32>
pop <mem>
```
*Examples*
`pop edi — pop the top element of the stack into EDI.`
`pop [ebx] — pop the top element of the stack into memory at the four bytes starting at location EBX.`
- **lea**— Load effective address
lea实际上是一个载入有效地址指令,将第二个操作数表示的地址载入到第一个操作数(寄存器)中。其语法如下所示:
*Syntax*
`lea <reg32>,<mem>`
*Examples*
`lea eax, [var] — var指示的地址载入eax中.`
`lea edi, [ebx+4*esi] — ebx+4*esi表示的地址载入到edi中,这实际是上面所说的寻址模式的一种表示方式.`
#### 算术和逻辑指令
- **add**— Integer Addition
add指令将两个操作数相加,且将相加后的结果保存到第一个操作数中。其语法如下所示:
```asm
add <reg>,<reg>
add <reg>,<mem>
add <mem>,<reg>
add <reg>,<con>
add <mem>,<con>
```
*Examples*
`add eax, 10 — EAX ← EAX + 10`
`add BYTE PTR [var], 10 — 10与var指示的内存中的一个byte的值相加,并将结果保存在var指示的内存中`
- **sub**— Integer Subtraction
sub指令指示第一个操作数减去第二个操作数,并将相减后的值保存在第一个操作数,其语法如下所示:
```asm
sub <reg>,<reg>
sub <reg>,<mem>
sub <mem>,<reg>
sub <reg>,<con>
sub <mem>,<con>
```
*Examples*
`sub al, ah — AL ← AL - AH`
`sub eax, 216 — eax中的值减26,并将计算值保存在eax中`
- **inc, dec**— Increment, Decrement
inc,dec分别表示将操作数自加1,自减1,其语法如下所示:
```asm
inc <reg>
inc <mem>
dec <reg>
dec <mem>
```
*Examples*
`dec eax — eax中的值自减1.`
`inc DWORD PTR [var] — *var指示内存中的一个4-byte值自加1`*
- **imul**— Integer Multiplication
整数相乘指令,它有两种指令格式,一种为两个操作数,将两个操作数的值相乘,并将结果保存在第一个操作数中,第一个操作数必须为寄存器;第二种格式为三个操作数,其语义为:将第二个和第三个操作数相乘,并将结果保存在第一个操作数中,第一个操作数必须为寄存器。其语法如下所示:
```asm
imul <reg32>,<reg32>
imul <reg32>,<mem>
imul <reg32>,<reg32>,<con>
imul <reg32>,<mem>,<con>
```
*Examples*
`imul eax, [var] — eax→ eax * [var]`
`imul esi, edi, 25 — ESI → EDI * 25`
- **idiv**— Integer Division
idiv指令完成整数除法操作,idiv只有一个操作数,此操作数为除数,而被除数则为EDX:EAX中的内容(一个64位的整数),操作的结果有两部分:商和余数,其中商放在eax寄存器中,而余数则放在edx寄存器中。其语法如下所示:
*Syntax*
`idiv <reg32>`
`idiv <mem>`
*Examples*
`idiv ebx`
`idiv DWORD PTR [var]`
- **and, or, xor**— Bitwise logical and, or and exclusive or
逻辑与、逻辑或、逻辑异或操作指令,用于操作数的位操作,操作结果放在第一个操作数中。其语法如下所示:
```asm
and <reg>,<reg>
and <reg>,<mem>
and <mem>,<reg>
and <reg>,<con>
and <mem>,<con>
or <reg>,<reg>
or <reg>,<mem>
or <mem>,<reg>
or <reg>,<con>
or <mem>,<con>
xor <reg>,<reg>
xor <reg>,<mem>
xor <mem>,<reg>
xor <reg>,<con>
xor <mem>,<con>
```
*Examples*
`and eax, 0fH — 将eax中的钱28位全部置为0,最后4位保持不变.`
`xor edx, edx — 设置edx中的内容为0.`
- **not**— Bitwise Logical Not
位翻转指令,将操作数中的每一位翻转,即0->1, 1->0。其语法如下所示:
`not <reg>`
`not <mem>`
*Example*
`not BYTE PTR [var] — *将var指示的一个字节中的所有位翻转*.`
- **neg**— Negate
取负指令。语法为:
`neg <reg>`
`neg <mem>`
*Example*
`neg eax — EAX → - EAX`
- **shl, shr**— Shift Left, Shift Right
位移指令,有两个操作数,第一个操作数表示被操作数,第二个操作数指示位移的数量。其语法如下所示:
```asm
shl <reg>,<con8>
shl <mem>,<con8>
shl <reg>,<cl>
shl <mem>,<cl>
shr <reg>,<con8>
shr <mem>,<con8>
shr <reg>,<cl>
shr <mem>,<cl>
```
*Examples*
`shl eax, 1 — Multiply the value of EAX by 2 (if the most significant bit is 0),左移1位,相当于乘以2`
`shr ebx, cl — Store in EBX the floor of result of dividing the value of EBX by 2*n* where *n* is the value in CL.`
#### 控制转移指令
X86处理器维持着一个指示当前执行指令的指令指针(IP),当一条指令执行后,此指针自动指向下一条指令。IP寄存器不能直接操作,但是可以用控制流指令更新。
> ```
> mov esi, [ebp+8]
> begin: xor ecx, ecx
> mov eax, [esi]
>
> ```
如第二条指令用begin指示,这种标签的方法在某种程度上简化了汇编程序设计,控制流指令通过标签实现程序指令跳转。
- **jmp** — Jump
控制转移到label所指示的地址,(从label中取出执行执行),如下所示:
`jmp <label>`
*Example*
`jmp begin — Jump to the instruction labeled begin.`
- **jcondition**— Conditional Jump
条件转移指令,条件转移指令依据机器状态字中的一些列条件状态转移。机器状态字中包括指示最后一个算数运算结果是否为0,运算结果是否为负数等。机器状态字具体解释请见微机原理、计算机组成等课程。语法如下所示:
```asm
je <label> (jump when equal)
jne <label> (jump when not equal)
jz <label> (jump when last result was zero)
jg <label> (jump when greater than)
jge <label> (jump when greater than or equal to)
jl <label> (jump when less than)
jle <label>(jump when less than or equal to)
```
*Example*
`cmp eax, ebx`
`jle done , 如果eax中的值小于ebx中的值,跳转到done指示的区域执行,否则,执行下一条指令。`
- **cmp**— Compare
cmp指令比较两个操作数的值,并根据比较结果设置机器状态字中的条件码。此指令与sub指令类似,但是cmp不用将计算结果保存在操作数中。其语法如下所示:
```asm
cmp <reg>,<reg>
cmp <reg>,<mem>
cmp <mem>,<reg>
cmp <reg>,<con>
```
*Example*
`cmp DWORD PTR [var], 10`
`jeq loop, `
比较var指示的4字节内容是否为10,如果不是,则继续执行下一条指令,否则,跳转到loop指示的指令开始执行
- **call**, **ret**— Subroutine call and return
这两条指令实现子程序(过程、函数等意思)的调用及返回。call指令首先将当前执行指令地址入栈,然后无条件转移到由标签指示的指令。与其它简单的跳转指令不同,call指令保存调用之前的地址信息(当call指令结束后,返回到调用之前的地址)。
ret指令实现子程序的返回机制,ret指令弹出栈中保存的指令地址,然后无条件转移到保存的指令地址执行。
call,ret是函数调用中最关键的两条指令。具体细节见下面一部分的讲解。语法为:
`call <label>`
`ret`
### 调用规则
调用规则分为两个方面,及调用者规则和被调用者规则,如一个函数A调用一个函数B,则A被称为调用者(Caller),B被称为被调用者(Callee)。
下图显示一个调用过程中的内存中的栈布局:
![调用栈](stack-convention.png)
在X86中,栈增长方向与内存编号增长方向相反。
#### Caller Rules
调用者规则包括一系列操作,描述如下:
1)在调用子程序之前,调用者应该保存一系列被设计为调用者保存的寄存器的值。调用者保存寄存器有eax,ecx,edx。由于被调用的子程序会修改这些寄存器,所以为了在调用子程序完成之后能正确执行,调用者必须在调用子程序之前将这些寄存器的值入栈。
2)在调用子程序之前,将参数入栈。参数入栈的顺序应该是从最后一个参数开始,如上图中parameter3先入栈。
3)利用call指令调用子程序。这条指令将返回地址放置在参数的上面,并进入子程序的指令执行。(子程序的执行将按照被调用者的规则执行)
当子程序返回时,调用者期望找到子程序保存在eax中的返回地址。为了恢复调用子程序执行之前的状态,调用者应该执行以下操作:
1)清除栈中的参数;
2)将栈中保存的eax值、ecx值以及edx值出栈,恢复eax、ecx、edx的值(当然,如果其它寄存器在调用之前需要保存,也需要完成类似入栈和出栈操作)
**Example**
如下代码展示了一个调用子程序的调用者应该执行的操作。此汇编程序调用一个具有三个参数的函数_myFunc,其中第一个参数为eax,第二个参数为常数216,第三个参数为var指示的内存中的值。
```asm
push [var] ; Push last parameter first
push 216 ; Push the second parameter
push eax ; Push first parameter last
call _myFunc ; Call the function (assume C naming)
add esp, 12
```
在调用返回时,调用者必须清除栈中的相应内容,在上例中,参数占有12个字节,为了消除这些参数,只需将ESP加12即可。
_myFunc的值保存在eax中,ecx和edx中的值也许已经被改变,调用者还必须在调用之前保存在栈中,并在调用结束之后,出栈恢复ecx和edx的值。
#### 被调用者规则
被调用者应该遵循如下规则:
1)将ebp入栈,并将esp中的值拷贝到ebp中,其汇编代码如下:
```asm
push ebp
mov ebp, esp
```
上述代码的目的是保存调用子程序之前的基址指针,基址指针用于寻找栈上的参数和局部变量。当一个子程序开始执行时,基址指针保存栈指针指示子程序的执行。为了在子程序完成之后调用者能正确定位调用者的参数和局部变量,ebp的值需要返回。
2)在栈上为局部变量分配空间。
3)保存callee-saved寄存器的值,callee-saved寄存器包括ebx,edi和esi,将ebx,edi和esi压栈。
4)在上述三个步骤完成之后,子程序开始执行,当子程序返回时,必须完成如下工作:
  4.1)将返回的执行结果保存在eax中
  4.2)弹出栈中保存的callee-saved寄存器值,恢复callee-saved寄存器的值(ESI和EDI)
  4.3)收回局部变量的内存空间。实际处理时,通过改变EBP的值即可:mov esp, ebp。
  4.4)通过弹出栈中保存的ebp值恢复调用者的基址寄存器值。
  4.5)执行ret指令返回到调用者程序。
After these three actions are performed, the body of the subroutine may proceed. When the subroutine is returns, it must follow these steps:
1. Leave the return value in EAX.
**Example**
```asm
.486
.MODEL FLAT
.CODE
PUBLIC _myFunc
_myFunc PROC
; Subroutine Prologue
push ebp ; Save the old base pointer value.
mov ebp, esp ; Set the new base pointer value.
sub esp, 4 ; Make room for one 4-byte local variable.
push edi ; Save the values of registers that the function
push esi ; will modify. This function uses EDI and ESI.
; (no need to save EBX, EBP, or ESP)
; Subroutine Body
mov eax, [ebp+8] ; Move value of parameter 1 into EAX
mov esi, [ebp+12] ; Move value of parameter 2 into ESI
mov edi, [ebp+16] ; Move value of parameter 3 into EDI
mov [ebp-4], edi ; Move EDI into the local variable
add [ebp-4], esi ; Add ESI into the local variable
add eax, [ebp-4] ; Add the contents of the local variable
; into EAX (final result)
; Subroutine Epilogue
pop esi ; Recover register values
pop edi
mov esp, ebp ; Deallocate local variables
pop ebp ; Restore the caller's base pointer value
ret
_myFunc ENDP
END
```
子程序首先通过入栈的手段保存ebp,分配局部变量,保存寄存器的值。
在子程序体中,参数和局部变量均是通过ebp进行计算。由于参数传递在子程序被调用之前,所以参数总是在ebp指示的地址的下方(在栈中),因此,上例中的第一个参数的地址是ebp+8,第二个参数的地址是ebp+12,第三个参数的地址是ebp+16;而局部变量在ebp指示的地址的上方,所有第一个局部变量的地址是ebp-4,而第二个这是ebp-8.
## AT&T 和 Intel 汇编语法的主要区别
- 首先,两者最让人纠结的区别就是源操作数、目标操作数的顺序。AT&T 语法先写源操作数,再写目标操作数;Intel 语法先写目标操作数,再写源操作数:
AT&T
```asm
movl %esp, %ebp
```
Intel
```asm
MOV EBP, ESP
```
- 然后,另一个明显的区别就是指令的命名(或者说,操作数大小的指定方式)。AT&T 语法将操作数的大小表示在指令的后缀中(b、w、l);Intel 语法将操作数的大小表示在操作数的前缀中(BYTE PTR、WORD PTR、DWORD PTR):
AT&T
```asm
decw (%eax)
```
Intel
```asm
DEC WORD PTR [EBX]
```
- 再者,各种取址方式的表示。AT&T 语法总体上是`offset(base, index, width)`的格式;Intel 语法总体上是`[INDEX * WIDTH + BASE + OFFSET]`的格式:
AT&T
```asm
movl 0x0100, %eax
movl (%esi), %eax
movl -8(%ebp), %eax
movl 0x0100(,%ebx,4), %eax
movl 0x8(%edx,%ebx,4), %eax
```
Intel
```asm
MOV EAX, [0100]
MOV EAX, [ESI]
MOV EAX, [EBP-8]
MOV EAX, [EBX*4+0100]
MOV EAX, [EDX+EBX*4+8]
```
- 另外,各种非十进制数制下数字的表示方法。AT&T 语法用前缀表示数制(0x、0、0b);Intel 语法用后缀表示数制(h、o、b):
AT&T
```asm
movl 0x8 , %eax
movl 010 , %eax
movl 0b1000, %eax
```
Intel
```asm
MOV EAX, 8h
MOV EAX, 10o
MOV EAX, 1000b
```
- 最后就是零碎的东西的表示方法了。AT&T 语法要在常数前加 $、在寄存器名前加 % 符号;Intel 语法没有相应的东西要加:
AT&T
```asm
subl $0x30, %eax
```
Intel
```asm
SUB EAX, 30
```
## 参考文档
- <https://segmentfault.com/a/1190000007977460>
- <http://www.cnblogs.com/YukiJohnson/archive/2012/10/27/2741836.html>
- <http://timothyqiu.com/archives/difference-between-att-and-intel-asm-syntax/>

0
content/posts/Win32汇编学习.md → content/posts/2018/Win32汇编学习/index.md

BIN
content/posts/2018/Win32汇编学习/stack-convention.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
content/posts/2018/Win32汇编学习/stackframe.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
content/posts/2018/Win32汇编学习/x86-registers.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

3
content/posts/office2016激活步骤.md → content/posts/2018/office2016激活步骤.md

@ -9,6 +9,7 @@ office2016激活方法。
<!--more--> <!--more-->
## 1. Retail版本转VOL版本 ## 1. Retail版本转VOL版本
```bat ```bat
cd /d "C:\Program Files (x86)\Microsoft Office\Office16" cd /d "C:\Program Files (x86)\Microsoft Office\Office16"
cscript ospp.vbs /dstatus cscript ospp.vbs /dstatus
@ -16,6 +17,7 @@ cscript ospp.vbs /dstatus
Retail版显示`LICENSE DESCRIPTION: Office 15, RETAIL(Grace) channel`,VOL版显示`LICENSE DESCRIPTION: Office 15, VOLUME_KMSCLIENT channel` Retail版显示`LICENSE DESCRIPTION: Office 15, RETAIL(Grace) channel`,VOL版显示`LICENSE DESCRIPTION: Office 15, VOLUME_KMSCLIENT channel`
- 32位版本Office转换代码 - 32位版本Office转换代码
```bat ```bat
@echo off @echo off
:ADMIN :ADMIN
@ -86,6 +88,7 @@ echo.
pause pause
``` ```
- 64位版本office转换代码 - 64位版本office转换代码
```bat ```bat
@echo off @echo off
:ADMIN :ADMIN

0
content/posts/为Ubuntu启用Swap分区.md → content/posts/2018/为Ubuntu启用Swap分区.md

BIN
content/posts/2018/加快Visual-Studio编译速度/after.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

BIN
content/posts/2018/加快Visual-Studio编译速度/before.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 B

4
content/posts/加快Visual-Studio编译速度.md → content/posts/2018/加快Visual-Studio编译速度/index.md

@ -49,9 +49,9 @@ Visual Studio并行编译选项命令为/MP,具体语法为:
以我自己的项目为例,不开启`/MP`选项,完整编译一次时间为48秒,开启之后完整编译一次时间为26秒。 以我自己的项目为例,不开启`/MP`选项,完整编译一次时间为48秒,开启之后完整编译一次时间为26秒。
{% asset_img before.png 不开启/MP选项 %} ![after](after.png)
{% asset_img after.png 开启/MP选项 %} ![before](before.png)
[^1]: 启用`/MP`编译选项 [^1]: 启用`/MP`编译选项

0
content/posts/动态获取当前模块的HMODULE-HINSTANCE值.md → content/posts/2018/动态获取当前模块的HMODULE-HINSTANCE值.md

BIN
content/posts/2018/流畅的Python学习笔记/frame13-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

BIN
content/posts/2018/流畅的Python学习笔记/frame7-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

4
content/posts/流畅的Python学习笔记.md → content/posts/2018/流畅的Python学习笔记/index.md

@ -1,6 +1,7 @@
--- ---
title: 《流畅的Python》学习笔记 title: 《流畅的Python》学习笔记
date: 2018-10-09 19:48:53 date: 2018-10-09 19:48:53
toc: true
tags: [python] tags: [python]
categories: python categories: python
--- ---
@ -279,6 +280,7 @@ avg(11)
在`averager`函数中,`series`是**自由变量(free variable)**。这是一个技术术语,指未在本地作用域中绑定的变量。 在`averager`函数中,`series`是**自由变量(free variable)**。这是一个技术术语,指未在本地作用域中绑定的变量。
{% asset_img frame7-1.png 自由变量 %} {% asset_img frame7-1.png 自由变量 %}
![自由变量](frame7-1.png)
综上,闭包是一种函数,它会保留定义函数时存在的自由变量的绑定,这样调用函数时,虽然定义作用域不可用了,但是仍然能使用那些绑定。 综上,闭包是一种函数,它会保留定义函数时存在的自由变量的绑定,这样调用函数时,虽然定义作用域不可用了,但是仍然能使用那些绑定。
@ -471,7 +473,7 @@ class Tombola(object): # python2
`__add__`, `__radd__`, `__iadd__` `__add__`, `__radd__`, `__iadd__`
{% asset_img frame13-1.png %} ![流程图](frame13-1.png)
### 众多比较运算符 ### 众多比较运算符
- 正向和反向调用使用的是同一系列方法。 - 正向和反向调用使用的是同一系列方法。

1
content/posts/解决chromium警告C4819.md → content/posts/2018/解决chromium警告C4819.md

@ -6,6 +6,7 @@ categories: chromium
--- ---
初次构建chromium的时候,可能会遇到错误 初次构建chromium的时候,可能会遇到错误
> : warning C4819: The file contains a character that cannot be represented in the current code page (936). Save the file in Unicode format to prevent data loss > : warning C4819: The file contains a character that cannot be represented in the current code page (936). Save the file in Unicode format to prevent data loss
> >
> : error C2220: warning treated as error - no 'object' file generated > : error C2220: warning treated as error - no 'object' file generated

18
content/posts/2019/hugo部署笔记.md

@ -0,0 +1,18 @@
---
title: "Hugo部署笔记"
date: 2019-07-26T22:08:48+08:00
draft: false
toc: false
images:
tags: [untagged]
---
使用的主题 <https://github.com/Track3/hermit>
遇到的坑:
- 目录过长时显示不全
代码获取:`git submodule add https://github.com/Track3/hermit.git themes/hermit`
从hexo迁移到hugo,还是有部分语法不一致的。

8
content/posts/others/_index.md

@ -0,0 +1,8 @@
---
title: "Others"
date: 2019-07-26T21:25:01+08:00
draft: false
toc: false
images:
---
Loading…
Cancel
Save