Win32-C++-Hello-World及程序运行

Win32编程系列文章:https://www.jianshu.com/nb/30332818

Win32编程可以实现GUI界面,具体可以参考微软官方给出的教程,下面介绍一下Hello World。

微软提供的入门基础HelloWorld程序见https://docs.microsoft.com/en-us/windows/desktop/learnwin32/your-first-windows-program

摘录代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#ifndef UNICODE
#define UNICODE
#endif

#include <windows.h>

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";

WNDCLASS wc = { };

wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;

RegisterClass(&wc);

// Create the window.

HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style

// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
NULL // Additional application data
);

if (hwnd == NULL)
{
return 0;
}

ShowWindow(hwnd, nCmdShow);

// Run the message loop.

MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return 0;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;

case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
EndPaint(hwnd, &ps);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
  • 使用方法
    我是在VS2017中使用的
    • 创建一个Windows窗口程序
    • 删除掉里面原有的文件
    • 设置项目属性C/C++-预编译头-不使用预编译头
    • 创建新的Cpp文件,内容是上面的代码
    • 运行即可
  • 这个东西其实就是一个代码的框架,写其他的时候直接在上面添加就行

django+nginx+uwsgi

  • nginx uwsgi
    • http://www.cnblogs.com/jhao/p/6071790.html
    • sudo apt-get install python-dev nginx
    • sudo pip install uwsgi --upgrade
    • 测试nginx:
      • 直接访问80端口
    • 测试uwsgi:
      • 如果还是使用80端口,就先把占80端口的nginx关掉……sudo pkill -9 nginx
      • 创建test.py
        • # test.py
          def application(env, start_response):
              start_response('200 OK', [('Content-Type','text/html')])
              return [b"Hello World"] 
          
      • sudo uwsgi --http :80 --plugin python --wsgi-file test.py
      • 出现Hello World即可
      • 删除test.py

一些用到的汇编库&函数

汇编系列文章:
https://www.jianshu.com/nb/29822876

可以直接到http://programming.msjc.edu/asm/help/上面搜索需要的函数。

库:
SmallWin.inc

Irvine32.inc

SetTextColor

  • http://programming.msjc.edu/asm/help/source/irvinelib/settextcolor.htm

  • Call args: EAX = Bits 0-3 = foreground color

                Bits 4-7 = background color
    

    Return arg: None

  • Example: Set for yellow text on blue background

    1
    2
    3
    4
    INCLUDE Irvine32.inc ;for color definitions

    mov eax,yellow+(blue*16)
    call SetTextColor
  • Note: The colors defined in Irvine32.inc are:
    black, white, brown, yellow, blue, green, cyan, red, magenta, gray, lightBlue, lightGreen, lightCyan, lightRed, lightMagenta, and lightGray.

汇编结构&宏

汇编系列文章:
https://www.jianshu.com/nb/29822876

Structure

定义

1
2
3
name STRUCT
field-declarations
name ENDS

也可以嵌套定义

声明变量

  • <...>里面写上对应的初始化参数,逗号隔开;<>表示默认的
  • varname structname <a,b,c>
  • 可以嵌套,声明时可以用尖括号和大括号

使用变量

  • 访问结构内变量直接用.
  • 但是不能直接使用储存地址的寄存器寻址后用.

Union

定义

1
2
3
name UNION
union-field-declarations
name ENDS

Macro

  • 有预处理器进行处理
  • 形式
    1
    2
    3
    macroname MACRO [parameter 1, 2...]
    statement-list
    ENDM
  • 避免缺少参数
    • IFB <row>if blank,检查是否row是空;之后用ENDIF
    • 缺省值:在param部分使用:=<...>
  • 使用IF、ELSE、ENDIF、LT(less than)、GT、EQ、等内容
  • IFIDNI可以比较输入和预设值,不带I表示区分大小写
  • 强制替换&,强制计算%,组合形成一个参数<>,转义!
  • EXITM返回内容
  • WHILE
  • REPEAT 次数
  • FOR color, <a,b>表示for color in [a, b]
  • FORC迭代字符串,FORC color, 表示for color in ‘JIOGE’

汇编String&Array

汇编系列文章:
https://www.jianshu.com/nb/29822876

Primitive instructions

1
2
3
4
5
MOVSB、MOVSW、MOVSD
CMP...
SCA... (scan)
STO... (store)
LOD... (load)
  • MOVSD之前给ESI、EDI赋值(target在edi),之后ESI、EDI会自动加/减4(MOVSB自动加/减1)
    • DF用于控制方向,有CLD(clear)和STD(set),0为加
    • 重复使用rep movsd,前面给ecx赋值
  • CMPSD
    • REPE/REPZREPNE/REPNZ,配合DF和ecx
    • 之后使用jajb
  • SCA..
    • 类似TEST,可以使用jejne
  • STO..
    • EDI中的偏移量表示一个地址,可以把AL/AX/EAX的内容写进EDI中存储的偏移量代表的内存位置中(D为destination),同时EDI会递增/递减
  • LOD..
    • 从ESI指向的内存地址加载到AL/AX/EAX,S为source,ESI会递增/递减

二维数组

  • 用基址变址操作数[base+index]、基址变址偏移量操作数[base+index+displacement]或者displacement[base+index]
  • 使用的是ebx, esi,64位用rbx, rsiebx是行首地址
  • STRUCT, ENDS定义结构体

汇编选择&循环结构

汇编系列文章:
https://www.jianshu.com/nb/29822876

Status flags

  • Zero、Carry(无符号溢出)、Sign(负数)、Overflow(有符号溢出)、Parity(低字节偶数个1)、Auxiliary Carry(第3bit到第4有进位)

逻辑操作

  • AND、OR、XOR、NOT
  • 可以与Bit-Mapped sets一起进行交集并集等操作
  • TEST:只进行and的检查,不改变操作数但会改变Zero flag。配合jz和jnz使用

CMP

  • 只改变flag,ZF、CF、OF等
  • 通过这些flag的改变。用Jcondition来跳转,包括:
    • JB、JC(b表示below,c表示carry flag)
    • JE、JZ(e表示equal,z表示zero flag)
    • JS(s表示sign)
    • JNE、JNZ(n为not)
    • JECXZ(表示ecx为zero)
  • JA、JB、JBE、JNA分别表示Unsigned的大于(above)、小于、小于等于、不大于
  • JG、JL、JNGE分别表示Signed的大于、小于、不大于等于(即小于)
  • Jcondition的操作数是代码label,对应机器码是EIP需要增大的数。由于在当前这一句时,EIP是在下一句,所以需要用目标label的地址减去下一句的地址

BT

  • BT bitBase, n是把bitBase的第n位放到Carry Flag里面
  • 之后可以用jc来跳转

LOOPZ&LOOPE

  • 依然有ECX的判断,但是必须ZF=1才能跳转
  • 同理有LOOPNE和LOOPNZ

伪指令

  • 可以使用.IF .ELSE .ENDIF .ELSEIF这几个指令(后面没有冒号)
  • 可以使用.REPEAT .UNTIL或者.WHILE .ENDW
  • 条件里面可以用与或非大小比较按位与的符号,以及CARRY?OVERFLOW?PARITY?SIGN?ZERO?,但是要注意顺序,不能写.IF 2 > eax之类的
  • SIGNED和UNSINGED的判断是通过数据label声明得到的,如果是寄存器默认认为UNSIGNED但是可以用SDWORD PTR来说明是signed