win32汇编·指令

  • 常用伪指令
    • 数字常量
    • 字符串常量
    • 预留空间
    • 复制重复
    • 符号定义伪指令
    • 等号伪指令
    • 操作符伪指令
    • 算术运算符
    • 逻辑操作符
    • 关系操作符
    • 框架定义
  • 样例
    • 函数声明语句
    • include 语句
    • 程序结束
    • 跨行语句
    • 数据存放
    • invoke伪指令
    • MessageBox
    • 输入输出有关的API函数
      • printf
      • scanf
  • 分支与循环
    • 单分支结构
    • 无符号类比
    • IF_THEN_ELSE结构
  • 升序数组查找一个数(折半查找)
    • SWITCH_CASE结构分支程序
  • 跳转表
    • 循环程序设计
  • 计算1+2+...+100用循环实现
  • 计算n的阶乘
  • 逻辑尺
  • 将一个字符串大写字符转换为小写字符
  • 多重循环设计-冒泡排序
  • 浮点运算
    • 浮点数规格化
    • 浮点数存储
      • 对单精度数Var1
      • 对双精度数Var2

[名字] 助记符 <操作数> [;注释]

常用伪指令

类型 助记符 简写 字节数 数字范围
字节 BYTE DB 1 0~255
WORD DW 2 0~65535
双节 DWORD DD 4
远节 FWORD DF 6
四节 QWORD DQ 8
十字节 TBYTE DT 10
带符号字节 SBYTE 1 -128~127
带符号字 SWORD 2 -32768~32767
带符号双字 SDWORD 4

数字常量

一个字节 8位 两位十六进制
十进制数:以D结尾,汇编默认十进制数,D可省略
二进制数:B
十六进制:H
八进制:Q或O

字符串常量

单引号,其值为ASCII
'A':41H
'ab':6162H

预留空间

?,不赋初值

复制重复

<n> DUP(操作数,...)

M1 DB 15,67H,11110000B,?
M2 DB '15','AB$'
M3 DW 4*5
M4 DD 1234H
M5 DB 2 DUP(5,'A')
M6 DW M2 ;M2的偏移量
M7 DD M2 ;M2偏移量,段基址0F 67 F0 00
31 35 41 42 24
14 00
34 12 00 00
05 41 05 41
04 00
04 00 xx xx

符号定义伪指令

符号名 EDQ 表达式

CR EQU 0DH ;CR表示回车符的ASCII
LF EQU 0AH ;LF表示换行符ASCII
PORT_B EQU 61H ;用PORT_B表示B端口61H
B EQU [BP+6] ;用B表示操作数[BP+6]MOV AL,CR ;(AL) = 0DH
ADD BL,B ;(BL) = (BL) + (SS:[BP+6])
IN AL,PORT_B ;从61H端口输入一个字节的数据
OUT PORT_B,AL ;再输出到61H端口

等号伪指令

符号名 = 数值表达式
只能是常数或数值表达式

DPL = 20H
K = 1

操作符伪指令

$
表示当前地址计数器的值

ORG 数值表达式
设置地址计数器内容为数值表达式的值

OFFSET [变量 | 标号]
取出变量或标号的地址

算术运算符

+ - * / MOD
/取商的整数部分
MOD取余数

逻辑操作符

AND OR XO NOT

关系操作符

EQ 等于
NE 不等于
LT 小于
LE 小于等于
GT 大于
GE 大于等于

框架定义

伪指令格式 功能
.DATA 定义数据段
.DATA? 定义存放为初始化变量的数据段
.CONST 定义存放常量的数据段
.CODE 定义代码段
.STARTUP 指定加载后的程序入口点
.EXIT 返回DOS或父进程
.STACK size 建立一个堆栈段并定义其大小(size以字节为单位。若未指定则默认为1KB)
.MODEL 内存模式[,调用规则][,其他模式] 定义程序工作的模式
Windows中,DATA,DATA?,CONST,STACK都视为数据区,堆栈空间一般是系统自动分配的,用户程序不必考虑

样例


.386:定义了程序使用30386指令集
.model flat:每一个程序都拥有其相对独立的4GB地址空间。因此Windows可执行程序只有一种内存模式,即flat模式,从00000000H到0FFFFFFFFH
srdcall:使用此规则调用子程序,堆栈平衡将由被调用者(子程序)用RET n指令实现。故在程序中调用Windows API函数或子程序后,不必调用者考虑堆栈平衡的问题
option:在Win32中需要定义option casemap:none用来说明程序中的变量和子程序名是否对大小写敏感。由于Windows API中的函数名称是区分大小写的,所以需要指定
includelib:汇编程序中调用一些外部模块来完成部分功能,例如printf放在msvcrt.dll动态链接库中

函数声明语句

函数名称 PROTO [调用规则]:[第一个参数类型][,:后续参数类型]
printf函数声明:
_CRTIMP int _cdecl printf(const char *, ...);
例如上例子中:
printf PROTO C:ptr sbyte,: VARARG
printf函数的调用规则为C调用规则(_cdecl,即c_declare),第一个参数是字符串指针,后面的参数数量及类型不定。如果函数使用C调用规则,则PROTO后跟一个C。接下来是参数的说明。如果参数个数、类型不定,则用VARARG说明。

汇编中,用ptrs byte 代表const char*

include 语句

include user32.inc
采用C语言办法,把所有函数声明及常量定义等公用部分预先放在一个头文件中

程序结束

END [过程名]
程序在遇到end语句时结束,end语句后指出程序执行的入口点,即装入执行的第一条指令的位置。

跨行语句

某语句过长,加\做换行符,将这句分成几行来写

数据存放

(1)可读可写初始变量:定义在data区
(2)可读可写未初始变量:可以在data,也可以在data?中
(3)常量数据:不需要修改已具有初值,放在const中,也可以在data中

invoke伪指令

invoke 函数名[,参数1][,参数2]

MessageBox


MessageBox属于usr32.dll,是Windows的一个API函数。
第一个参数是一个窗口句柄,即消息框父窗口,这里使用NULL表示它没有父窗口。
第二个参数是一个字符串指针,指向消息框中显示的正文。
第三个参数也是一个字符串指针,指向在消息框的窗口标题。
第四个参数是一个整数,指定消息框类型,这里使用MB_OK,消息框中显示一个OK(确定)按钮。

输入输出有关的API函数

所有用到的库函数,在程序开始部分必须预先声明,包括函数名称、参数类型。
函数名称 PROTO [调用规则]:[第一个参数类型][,:后续参数类型]
调用规则是可选项, 可以是stdcall,也可以是C等。缺省时使用model语句中指定的调用规则。
如果函数使用C调用规则,则PROTO后跟一个C。
参数的说明中如果参数个数、类型不定,则用VARARG说明

printf

在C语言头文件stdio.h中printf函数声明为:
_CRTIMP int _cdecl printf(const char *, ...);
调用规则为C调用规则(_cdecl,即c_declare),第一个参数是字符串指针,后面的参数数量及类型不定。

printf PROTO C:ptrs byte,:varargs
实际上调用时只注重它的类型,并不关心其名称,因此在程序中参数类型经常用DWORD来表示,他可以代表字符串指针、结构指针、整数等,例如printf也可以声明为:
printf PROTO C:dword,:varargs

printf及其他msvcrt.dll 输出的函数的连接信息豆子这个库文件中。因此在程序开头应有以下语句:
include lib msvcrt.lib

invoke printf, offset szOut,x,n,p
其中,szOut要在数据区中定义,如:
szOut byte 'x=%d n=%d x(n)=%d',0ah,0
效果等价于:
printf("x=%d n=%d x(n)=%d\n",x,n,p);

scanf

scanf链接信息也在msvcrt.lib库中。调用规则和参数类型说明为:
scan PROTO C:dword,:vararg
第一个参数是格式化字符串地址,后面参数个数可变,可以一个没有
szlnFmtStr byte '%d %c %d',0
invoke scant, offset szlnFmtStr,offset a,offset b,offset d
第一个参数是格式化字符串szlnFmtStr地址
第2,3,4个参数分别是a,b,d地址,效果等价于:
scanf("%d %c %d",&a,&b,&d);

分支与循环

单分支结构

求带符号数A和B的MAX_AB = MAX(A,B)

MOV EAX,A
CMP EAX,B
JGE AlsLarger ;如果A≥B,跳转到AlsLarger标号处
MOV EAX,B
AlsLarger:
MOV MAXAB,EAX

无符号类比

求无符号数A和B的MAX_AB = MAX(A,B)

MOV EAX,A
CMP EAX,B
JAE AlsAbove ;如果A≥B,跳转到AlsAbove标号处
MOV EAX,BAlsAbove:
MOV MAXAB,EAX

IF_THEN_ELSE结构

求带符号数X符号,如果X≥0,把SIGNX置为1;如果X<0,SIGNX置为-1

X SDWORD 45
SIGNX SDWORD ?MOV SIGNX,0
CMP X,0
JGE XisPostive ;X≥0跳转
MOV SIGNX,-1
JMP HERE ;这样可以跳过MOV SIGNX,1XisPostive:
MOV SIGNX,1HERE:

升序数组查找一个数(折半查找)

数组名dArray,数组字节型,下标为EBX,在程序中用dArray[EBX]来表示下标为EBX的元素

.386
.model flat,stdcall
option casemap:noneincludelib msvcrt.lib
printf PROTO C:dword,:VARARG.DATA
dArray byte 15,27,39,40,68,71,82,100,200,230
Items equ ($-dArray) ;定义数组中元素个数
Element byte 83 ;假设查找的数字为82
Index dword ? ;在数组中的序号
Count dword ? ;查找的次数
szFmt byte 'Index=%d Count=%d Element=%d',0ah,0 ;输出格式字符串
szErrMsg byte 'Not Found, Count=%d Element=%d',0ah,0.CODE
start:xor eax,eax ;xor相同则置为0,相当于清空了mov Index,-1 ;赋初值,假设找不到mov Count,0 ;赋初值,查找次数为0mov esi,0 ;ESI表示查找范围的下届mov edi,Items-1 ;EDI表示查找范围的上届mov al,Element ;EAX是要在数组中查找的数字
Compare:cmp esi,edi ;下界是否超过上届jg NotFound ;如果下界超过上届,未找到mov ebx,esi ;取下界和上届的中点add ebx,edi ;shr ebx,1   ;EBX右移一位,相当于EBX=(ESI+EDI)/2inc Count ;查找次数+1cmp al,dArray[ebx] ;与中点上的元素比较jz Found ;相等则查找结束ja MoveLow ;较大则移动下界,取上半段,故将下界设为中点mov edi,ebx ;较小,移动上界,取下半段,故将上界设为中点dec edi ;ebx中点位置已经比较过,不再比较,自减1jmp Compare ;范围缩小后,继续查找
MoveLow:mov esi,ebx ;较大,移动下界inc esi ;ebx中点位置已经比较过,不再比较,自增1jmp Compare ;范围缩小后,继续查找
Found:mov Index,ebx ;找到,ebx是下标xor eax,eaxmov al,dArray[ebx]invoke printf,offset szFmt,Index,Count,eaxret
NotFound:invoke printf,offset szErrMsg,Count,eaxret
end start

SWITCH_CASE结构分支程序

编制一个管理文件的菜单程序,要求能够实现建立文件、修改文件、删除文件、显示文件和退出应用程序5个主控功能。首先在屏幕上显示5种功能,然后从键盘上输入数字1~5即可转入相应的功能,而输入其他字符则提示输入非法。若选择退出功能,则能正确返回;若选择其他功能,应能返回到主菜单。

对于SWITCH_CASE结构,由于分支众多,可以把各分支入口地址集中在一起构成一个地址表,把这个地址表称为跳转表。设建立文件分支入口标号为CR,修改文件分支入口标号为UP,删除文件分支入口标号为DE,显示文件分支入口标号为PR,退出分支入口标号为QU。

JMPTAB DD OFFSET CR ;跳转表DD OFFSET UPDD OFFSET DEDD OFFSET PRDD OFFSET QU

跳转表

索引号=K-起始功能号(例如功能号为1,2,3,…,N,则索引号=K-1,相当于一个从0开始,一个从1开始)。
位移量=索引号×每项入口地址占用的字节数。对于用DD定义的则为4字节。
表项地址=表基址+位移量。

.386
.model flat,stdcall
option casemap:noneincludelib msvcrt.lib
printf PROTO C:ptr sbyte,:VARARG
scanf PROTO C:ptr sbyte,:VARARG.DATA
Msg1 db '1--create',0ah ;菜单字符串db '2--update',0ahdb '3--delete',0ahdb '4--print',0ahdb '5--quit',0ah,0
Msg2 db 'input select:',0ah,0 ;输入提示字符串
Fmt2 db '%d',0 ;scanf格式字符串
op dd ? ;scanf结果(用户输入的整数)
Msg3 db 'Error!',0ah,0 ;输入错误后显示的字符串
MsgC db 'Create a File',0ah,0 ;选择菜单一后显示的字符串
MsgU db 'Update a File',0ah,0 ;选择菜单二后显示的字符串
MsgD db 'Delete a File',0ah,0 ;选择菜单三后显示的字符串
MsgP db 'Print a File',0ah,0 ;选择菜单四后显示的字符串
MsgQ db 'Quit',0ah,0 ;选择菜单五后显示的字符串
JmpTab dd offset CR ;跳转表,保存5个符号dd offset UPdd offset DEdd offset PRdd offset QU.CODE
start:invoke printf,offset Msg1
Rdkb:invoke printf,offset Msg2 ;显示提示invoke scanf,offset Fmt2,offset opcmp op,1 ;与1比较jb Beep ;输入的数字比1小,不合法cmp op,5 ja Beep ; 输入的数字比5大,不合法mov ebx,opdec ebx ;减1得到索引值jmp JmpTab[ebx*4] ;得到表项对应的标号,并跳转过去
Beep:invoke printf,offset Msg3 ;提示输入错误jmp Rdkb
CR:invoke printf,offset MsgCjmp start ;回到主菜单,继续运行
UP:invoke printf,offset MsgUjmp start
DE:invoke printf,offset MsgDjmp start
PR:invoke printf,offset MsgPjmp start
QU:invoke printf,offset MsgQret ;返回系统
end start

循环程序设计


(1)循环初始化。它包括设置循环次数的初始值、地址指针的初始设置等。
(2)循环体。这是循环工作的主体,包括要重复执行的操作,以及循环的修改部分。修改部分包括地址指针的修改、循环控制条件的修改等。
(3)循环控制部分。它是控制循环的关键,判断循环条件满足与否。例如判断循环次数是否为0等。

计算1+2+…+100用循环实现

.386
.model flat,stdcall
option casemap:noneincludelib msvcrt.lib
printf PROTO C:ptr sbyte,:VARARG.DATA
sum dword 0
szMsg db 'ecx=%d eax=%d sum=%d',0ah,0.CODE
start:mov ecx,100mov eax,1
d10:add sum,eaxinc eaxloop d10invoke printf,offset szMsg,ecx,eax,sumret
end start

计算n的阶乘

.386
.model flat,stdcall
option casemap:noneincludelib msvcrt.lib
printf PROTO C:ptr sbyte,:VARARG.DATA
Fact dword ?
N equ 6
szFmt db 'factorial(%d)=%d',0ah,0.CODE
start:mov ecx,N ;循环初值mov eax,1 ;Fact初值
e10:imul eax,ecx ;Fact=Fact*ecxloop e10 ;循环N次mov Fact,eaxinvoke printf,offset szFmt,N,Factret
end start

逻辑尺

设数组X、Y中分别存有10个双字型数据。试实现以下计算并把结果存入Z单元。
Z1=X1+Y1 Z2=X2+Y2 Z3=X3-Y3 Z4=X4-Y4 Z5=X5-Y5 Z6=X6+Y6 Z7=X7-Y7 Z8=X8-Y8 Z9=X9+Y9 Z10=X10+Y10
10组数进行运算,运算操作符不同,且无规律可循。若直接用前边介绍的循环程序难以实现。这里设想把加用某个值表示(设用 0),减用另一个值表示(设用1),10个式子的操作用10位二进制数表示。对于本例,若按Z10、Z9、…、Z1的计算顺序把它们的操作符自右至左排列起来,则操作符数值化后得到一串二进制位0011011100,把它放入一个32位的内存变量中,高22位无意义 (此处用0填充),这种存储单元一般被叫做逻辑尺。计算时按照Z1…Z10顺序,先求Z1的值。每次把逻辑尺右移一位,对移出位进行判断,若该位为0则加,为1则减。

.386
.model flat,stdcall
option casemap:noneincludelib msvcrt.lib
printf PROTO C:ptr sbyte,:VARARG.DATA
x dd 1,2,3,4,5,6,7,8,9,10
y dd 5,4,3,2,1,10,9,8,7,6
Rule dd 0000000011011100B
z dd 10 dup(?)
szFmt db 'Z[%d] = %d',0ah,0.CODE
start:mov ecx,10 ;循环初值,loop对应此初值mov edx,Rule ;逻辑尺mov ebx,0
next:mov eax,x[ebx] ;取x中的一个数shr edx,1 ;逻辑尺右移一位jc subs ;分支判断并实现转移add eax,y[ebx] ;两数加jmp short result
subs:sub eax,y[ebx] ;两数减
result:mov z[ebx],eax ;存结果add ebx,4 ;修改地址指针loop nextxor ebx,ebx ;清空ebx,地址偏移
PrintNext:invoke printf,offset szFmt,ebx,z[ebx*4] ;打印结果inc ebx ;ebx下标+1cmp ebx,10 ;是否已经全部打印jb PrintNext ;继续打印ret
end start

将一个字符串大写字符转换为小写字符

要求:字符串以0结尾
分析:大写字符的ASCII码值为41H~5AH,小写字符的ASCII码值为61H~7AH。对大写字符,将它加上20H,即可以转换为小写字符。当遇到字符0时,循环结束。

.386
.model flat,stdcall
option casemap:noneincludelib msvcrt.lib
printf PROTO C:ptr sbyte,:VARARG.DATA
szStr db 'Hello World!',0.CODE
start:mov esi,offset szStr
g10:mov al,[esi]cmp al,0jz g30 ;判断为0说明走到尾了cmp al,'A' ;小于A说明是普通字符jb g20cmp al,'Z' ;大于Z说明是小写字符和普通字符ja g20add al,'a'-'A'mov [esi],al
g20:inc esijmp g10
g30:invoke printf,offset szStrret
end start

多重循环设计-冒泡排序

把数组中的7个元素用冒泡法按从小到大的顺序排列
在设计冒泡排序的程序时,需要两层循环。外层循环的循环次数是n-1,以第0次、第1次、…、第n-2次循环表示。第i次外循环中,内层循环对数组下标为0至n-i-1的元素依次“比较、交换”。内层循环的循环次数是n-i-1。

//C形式
void bubbleSort(int arr[], int len)
{int temp;for (int i = len -1; i > 0; i--){//外循环为排序趟数,len个数进行len-1趟for (int j = 0; j < i; j++){ //内循环为每趟比较的次数,第i趟比较len-i次if (arr[j] > arr[j + 1]){ //相邻元素比较,若逆序则交换(升序为左大于右,降序反之) temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}
.386
.model flat,stdcall
option casemap:noneincludelib msvcrt.lib
printf PROTO C:ptr sbyte,:VARARG
scanf PROTO C:ptr sbyte,:VARARG.DATA
dArray dd 20,15,70,30,32,89,12
items equ ($-dArray)/4 ;数组中元素个数
szFmt db 'dArray[%d]=%d',0ah,0.CODE
start:mov ecx,items-1
i10:xor esi,esi
i20:mov eax,dArray[esi*4]mov ebx,dArray[esi*4+4]cmp eax,ebxjl i30 ;排序满足需求,不用交换mov dArray[esi*4],ebxmov dArray[esi*4+4],eax
i30:inc esi ;递增一个cmp esi,ecx ;比总数小则再来一个内循环jb i20loop i10 ;(ecx-1),同时进行外循环xor edi,edi
i40:invoke printf,offset szFmt,edi,dArray[edi*4]inc edicmp edi,itemsjb i40ret
end start

浮点运算

专用于数值计算的浮点运算指令,包括浮点数的传送、浮点算术运算、浮点比较与控制等。
浮点处理单元x87 FPU
IEEE浮点数格式

浮点数规格化

规格化浮点数的尾数域最左位(最高有效位)总是1,故这一位经常不予存储,而认为隐藏在小数点的左边。否则以修改阶码同时左右移小数点位置的办法,使其变为规格化数的形式。
在浮点数格式中,扩展双精度类型没有隐含位,因此它的有效位数与尾数位数一致,而单精度类型和双精度类型均有一个隐含整数位,因此它的有效位数比位数多一个。

浮点数存储

float Var1 = 119.054f; //定义float型变量Var1,f强制为单精度浮点型
double Var2 = 119.054; //定义double型变量Var2
int main()
{Var1 = Var1;Var2 = Var2;return 0;
}

对应的汇编码

6: Var1 = Var1;
0040E6B8 mov eax,[Var1(00426608)]
0040E6BD mov [Var1 (00426608)],eax
7: Var2 = Var2;
0040E6C2 mov ecx,dword ptr [Var2 (00426610)]
0040E6C8 mov dword ptr [Var2 (00426610)],ecx
0040E6CE mov edx,dword ptr [Var2+4 (00426614)]
0040E6D4 mov dword ptr [_Var2+4 (00426614)],edx
8: return 0;
0040E6DA xor eax,eax

对单精度数Var1

从内存00426608处取出变量Var1保存的值为:A6 1B EE 42,转化 为二进制(逆序存放):
01000010 11101110 00011011 10100110
根据单精度的划分方式把32位划分成三部分:
1.符号位为0,为正数;
2.指数为 10000101(133),减去127得6(移码);
3.尾数加上1后为1.11011100001101110100110,十进制表示为: 1.86021876
尾数乘以2的6次方后可得结果为:119.05400(单精度7~8位有效数字)

对双精度数Var2

从内存00426610和00426614处取出变量Var1保存的值为:FA 7E 6A BC 74 C3 5D 40,转化为二进制(逆序存放):
01000000 01011101 11000011 01110100 10111100 01101010 01111110 11111010
1.符号位为0,为正数;
2.指数为10000000101(1029),减去1023得6;
3.尾数加上1后为 1.1101110000110111010010111100011010100111111011111010
转化为10进制后乘以2的6次方后可得结果为119.054000000000 (双精度15~16位有效数字)

win32汇编·指令相关推荐

  1. win32汇编指令汇总

    -----------------------算数运算指令----------------------- ADD          加法 ADC          带位加法 SBB           ...

  2. 学习win32汇编指令:lea和offset

    主要来源:http://topic.csdn.net/t/20061216/21/5235706.html#r_achor lea   是机器指令,offset   是伪指令. LEA  BX,  B ...

  3. 【win32汇编】0x01 开篇一些乱七八糟的话

    之前弄完了16位汇编,现在正式学习win32汇编,首先就是一些原理了,其实就是在16位的基础上增加了一些内容,其程序主要的结构记录如下 (1)指令集     .386     这是指定指令集 必须工作 ...

  4. Windows内核 基本汇编指令

    1)用VS2010新建Win32 Console Application,工程名为ACECore,工程建立完成后得到打开文件ACECore.cpp,代码如下: #include "stdaf ...

  5. Win32汇编_基础

    Win32汇编_基础 包含全部段的源程序结构: .386 .model flat, stdcall Option casemap:none ;<一些include语句> .stack [堆 ...

  6. win32汇编实现拼接SQL语句

    字符串合并,在汇编语言,一般是用loop循环和cx寄存器,自己编程实现: 如果是win32汇编,可以使用movsb指令: 一般开发应用程序都会碰到拼接SQL语句,在C#这些语言用字符串连接的加号就可以 ...

  7. Win32汇编基本编程框架

    Win32汇编编程框架如下: .386 .model flat,stdcall option casemap:none <一些include语句> .stack [堆栈段的大小] .dat ...

  8. Win32 汇编语句模板

    Win32 汇编语句模板 一 变量 ;句柄 hInstance dd 0 hWnd dd 0 hPen dd 0 hPend dd 0 oldPen dd 0;过程变量 hInst :DWORD hP ...

  9. 浅析VS2010反汇编 VS 反汇编方法及常用汇编指令介绍 VS2015使用技巧 调试-反汇编 查看C语言代码对应的汇编代码...

    浅析VS2010反汇编 2015年07月25日 21:53:11 阅读数:4374 第一篇 1. 如何进行反汇编 在调试的环境下,我们可以很方便地通过反汇编窗口查看程序生成的反汇编信息.如下图所示. ...

最新文章

  1. 杀掉某个进程的 Shell
  2. java jdk下载过慢 解决方案
  3. Android自动播放下一曲,环信Android自动播放下一条语音
  4. 判断可逆素数的c语言程序,C语言可逆素数教程
  5. html 字体思源_CSS font-family 各字体一览表
  6. bat篇---windows bat启动exe结尾的可执行程序
  7. 朗文3000词汇表带音标_牛津3000词汇表
  8. dtu转发虚拟服务器,DTU转发云服务器
  9. 7-8 哈利·波特的考试 (25分) 【最短路径】
  10. 读书是走马观花还是咬文嚼字?
  11. 06年及以前韩国星际职业联赛及选手资料
  12. 【ps功能精通】1.简单了解PS
  13. Hey AI,请写一首披头士风格的歌给我
  14. Navicat for MySQL(三叶草)破解工具
  15. android elf 加固_Android so加固的简单脱壳
  16. ​MYSQL中常用的SQL语句​(增删改查)
  17. 电子邮件管理系统 android,IM800电子邮件管理系统
  18. c语言马里超级奥游戏代码,超级玛格奥下载-超级玛格奥游戏下载v2.0下载-99wo下载站...
  19. jsp 如何 返回数据库数据供前端访问 /简单的jsp接口如何编写 /jsp如何链接数据库
  20. SpringBoot工程接入腾讯云短信服务平台

热门文章

  1. ae导出gif插件_AE不可以导出GIF图?我来教你啦
  2. 中职网络搭建 域用户密码设置
  3. 码率(Bitrate)、帧率(FPS)、分辨率和清晰度的联系与区别
  4. python怎么复制字符串_python字符串复制的几种方法
  5. Hello PyQt5(一)PyQt5简介
  6. pyqt5——设置窗口背景
  7. 贵州支教之第四天(11月10日)
  8. 从七岁到二十七岁的二十年
  9. flot.js ajax,如何画Flot实时更新图
  10. [LOJ]#572. 「LibreOJ Round #11」Misaka Network 与求和 min_25筛+杜教筛