0 写在前面

  为了更深入的了解程序的实现原理,近期我学习了IBM-PC相关原理,并手工编写了一些x86汇编程序。

  在2017年的计算机组成原理中,曾对MIPS体系结构及其汇编语言有过一定的了解,考虑到x86体系结构在目前的广泛应用,我通过两个月左右的时间对x86的相关内容进行了学习。

  在《x86汇编语言实践》系列中(包括本篇、x86汇编语言实践(1)x86汇编语言实践(3)x86汇编语言实践(4)以及x86汇编语言复习笔记),我通过几个具体案例对x86汇编语言进行实践操作,并记录了自己再编写汇编代码中遇到的困难和心得体会,与各位学习x86汇编的朋友共同分享。

  我将我编写的一些汇编代码放到了github上,感兴趣的朋友可以点击屏幕左上角的小猫咪进入我的github,或请点击这里下载源代码。

1 十进制输入输出的乘法练习

1-1 练习要点

  • 输入输出中断调用练习
  • 宏练习
  • 子程序编写与调用

1-2 实现思路

  • 数据区使用byte类型存放两个十进制乘数NUM1和NUM2
  • 输入采用宏GETNUM实现,从百位读到个位,调用乘法宏MULTI计算出NUM1和NUM2的值
  • 调用乘法宏MULTI计算出结果,并保存到RESULT,以便debug调试
  • 调用OUTPUT子程序进行输出,输出从RESULT中保存的结果
  • 其他对于输入输出的控制对输出结果进行改进

1-3 代码实现

  1. STACK SEGMENT PARA STACK
  2. DW 100H DUP(?)
  3. STACK ENDS
  4.  
  5. DATA SEGMENT PARA
  6. NUM1 DB ?
  7. NUM2 DB ?
  8. RESULT DW ?
  9. DATA ENDS
  10.  
  11. CODE SEGMENT PARA
  12. ASSUME CS:CODE,DS:DATA,SS:STACK
  13.  
  14. GETNUM MACRO
  15. MOV AH,
  16. INT 21H
  17. SUB AL,30H
  18. ENDM
  19.  
  20. MULTI MACRO N1,N2
  21. MOV AL,N1
  22. MOV BL,N2
  23. MUL BL
  24. ENDM
  25.  
  26. DIVIDE MACRO N1,N2
  27. MOV AX,N1
  28. MOV BX,N2
  29. XOR DX,DX
  30. DIV BX
  31. ENDM
  32.  
  33. DISPNUM MACRO
  34. PUSH DX
  35. MOV AH,
  36. MOV DL,AL
  37. ADD DL,30H
  38. INT 21H
  39. POP DX
  40. ENDM
  41.  
  42. INPUT MACRO NUM
  43. GETNUM
  44. MULTI AL,
  45. MOV NUM,AL
  46. GETNUM
  47. MULTI AL,
  48. ADD NUM,AL
  49. GETNUM
  50. ADD NUM,AL
  51. ENDM
  52.  
  53. NEWLINE MACRO
  54. MOV AH,
  55. MOV DL,0DH
  56. INT 21H
  57. MOV AH,
  58. MOV DL,0AH
  59. INT 21H
  60. ENDM
  61.  
  62. OUTPUT PROC
  63. DIVIDE AX,
  64. DISPNUM
  65. DIVIDE DX,
  66. DISPNUM
  67. DIVIDE DX,
  68. DISPNUM
  69. DIVIDE DX,
  70. DISPNUM
  71. MOV AL,DL
  72. DISPNUM
  73. RET
  74. OUTPUT ENDP
  75.  
  76. MAIN PROC FAR
  77. MOV AX,DATA
  78. MOV DS,AX
  79. ;get num1
  80. INPUT NUM1
  81. ;getchar
  82. GETNUM
  83. XOR AX,AX
  84. ;get num2
  85. INPUT NUM2
  86. ;num1 * num2
  87. MULTI NUM1,NUM2
  88. MOV RESULT,AX
  89. ;newline
  90. NEWLINE
  91. ;output result
  92. MOV AX,RESULT
  93. CALL OUTPUT
  94.  
  95. EXIT: MOV AX,4C00H
  96. INT 21H
  97. MAIN ENDP
  98.  
  99. CODE ENDS
  100. END MAIN

1-4 实现效果截图

经验证,发现输出结果符合预期。

2 字符串操作与跳转表练习

2-1 练习要点

  • 字符串的操作,包括:字符串的拼接、比较、查找
  • 子程序调用与宏
  • 跳转表的使用

2-2 重点难点

  • 子程序调用需要对子程序中使用到的变量进行压栈处理,以免变量污染
  • 字符串操作通常都需要对ES:DI和DS:SI进行初始化
  • 宏的内容不能有标签

2-3 实现思路

  • 首先为输入和输出单独编写子程序,程序主体采用跳转表实现
  • 为每一个条件单独编写一个子程序,有4个条件,因此共需编写4个子程序

2-4 代码实现

  1. STACK SEGMENT PARA STACK
  2. DW 100H DUP(?)
  3. STACK ENDS
  4.  
  5. DATA SEGMENT PARA
  6. LEN EQU
  7. MSG1 DB 'INPUT OPRAND:',,,'$' ;THE MSG TO OUTPUT
  8. MSG2 DB 'INPUT STRING 1:',,,'$'
  9. MSG3 DB 'INPUT STRING 2:',,,'$'
  10. MSG4 DB '<','$'
  11. MSG5 DB '=','$'
  12. MSG6 DB '>','$'
  13. MSG7 DB 'S3=','$'
  14. MSG8 DB 'INPUT A CHAR:',,,'$'
  15. MSG9 DB 'CHAR FOUND IN STR1!',,,'$'
  16. MSG10 DB 'CHAR NOT FOUND IN STR1!',,,'$'
  17. STR1 DB LEN-
  18. DB ?
  19. DB LEN DUP(?)
  20. STR2 DB LEN-
  21. DB ?
  22. DB LEN DUP(?)
  23. STR3 DB LEN-
  24. DB ?
  25. DB LEN DUP(?)
  26. CHAR DB ?
  27. OP DB ? ;THE OPRAND USER INPUT
  28. DATA ENDS
  29.  
  30. CODE SEGMENT PARA
  31. ASSUME CS:CODE,DS:DATA,SS:STACK
  32.  
  33. HINT MACRO MSG
  34. LEA DX,MSG ;OUTPUT MSG1
  35. MOV AH,09H
  36. INT 21H
  37. ENDM
  38.  
  39. GETOP MACRO
  40. MOV AH,
  41. INT 21H
  42. SUB AL,30H
  43. MOV OP,AL
  44. ENDM
  45.  
  46. NEWLINE MACRO
  47. PUSH AX
  48. PUSH DX
  49. MOV AH,
  50. MOV DL,0DH
  51. INT 21H
  52. MOV AH,
  53. MOV DL,0AH
  54. INT 21H
  55. POP DX
  56. POP AX
  57. ENDM
  58.  
  59. GETCHAR MACRO
  60. MOV AH,
  61. INT 21H
  62. MOV CHAR,AL
  63. ENDM
  64.  
  65. GETSTR1 PROC
  66. MOV DX,OFFSET STR1
  67. MOV AH,0AH
  68. INT 21H
  69. MOV CL,STR1+
  70. XOR CH,CH
  71. MOV SI,OFFSET STR1+
  72. LP1: INC SI
  73. LOOP LP1
  74. MOV BYTE PTR [SI],'$'
  75. RET
  76. GETSTR1 ENDP
  77.  
  78. GETSTR2 PROC
  79. MOV DX,OFFSET STR2
  80. MOV AH,0AH
  81. INT 21H
  82. MOV CL,STR2+
  83. XOR CH,CH
  84. MOV SI,OFFSET STR2+
  85. LP2:INC SI
  86. LOOP LP2
  87. MOV BYTE PTR [SI],'$'
  88. RET
  89. GETSTR2 ENDP
  90.  
  91. STRCAT PROC
  92. PUSH AX
  93. CLD
  94. CAT_LP1:LODSB
  95. STOSB
  96. CMP AL,
  97. JNZ CAT_LP1
  98. POP AX
  99. RET
  100. STRCAT ENDP
  101.  
  102. P2_PUTEND PROC
  103. MOV CL,STR1+ ;SET CX TO LEN FOR LOOP
  104. ADD CL,STR2+
  105. XOR CH,CH
  106. MOV SI,OFFSET STR3+ ;GET ACTUAL STRING
  107. PLP2: INC SI
  108. LOOP PLP2
  109. MOV BYTE PTR [SI],'$' ;PUT END TO STRING
  110. RET
  111. P2_PUTEND ENDP
  112. ;STRCMP
  113. P1 PROC
  114. PUSH CX
  115. CLD
  116. PUSH SI
  117. MOV CX,
  118. SLP1: LODSB
  119. CMP AL,00H
  120. JZ SLP1_1
  121. INC CX
  122. JMP SHORT SLP1
  123. SLP1_1: POP SI
  124. REPE CMPSB
  125. HINT STR1+
  126. JA SL1
  127. JB SL2
  128. HINT MSG5
  129. MOV AL,
  130. JMP SHORT RETURN
  131. SL1: HINT MSG6
  132. MOV AL,
  133. JMP SHORT RETURN
  134. SL2: HINT MSG4
  135. MOV AL,
  136. RETURN: HINT STR2+
  137. POP CX
  138. RET
  139. P1 ENDP
  140. ;STRCAT(S1,S2)+STRCPY(S3,S1)
  141. P2 PROC
  142. ;STRCAT(S1,S2)
  143. PUSH AX
  144. MOV SI,OFFSET STR2+
  145. MOV CL,STR1+
  146. XOR CH,CH
  147. MOV DI,OFFSET STR1+
  148. CATLP1: INC DI
  149. LOOP CATLP1
  150. CALL STRCAT
  151. ;STRCPY(S3,S1)
  152. MOV SI,OFFSET STR1+
  153. MOV DI,OFFSET STR3+
  154. CALL STRCAT
  155. CALL P2_PUTEND
  156. HINT MSG7
  157. HINT STR3+
  158. POP AX
  159. RET
  160. P2 ENDP
  161. ;STRCAT(S2,S1)+STRCPY(S3,S2)
  162. P2_2 PROC
  163. ;STRCAT(S2,S1)
  164. PUSH AX
  165. MOV SI,OFFSET STR1+
  166. MOV CL,STR2+
  167. XOR CH,CH
  168. MOV DI,OFFSET STR2+
  169. CATLP2: INC DI
  170. LOOP CATLP2
  171. CALL STRCAT
  172. ;STRCPY(S3,S1)
  173. MOV SI,OFFSET STR2+
  174. MOV DI,OFFSET STR3+
  175. CALL STRCAT
  176. CALL P2_PUTEND
  177. HINT MSG7
  178. HINT STR3+
  179. POP AX
  180. RET
  181. P2_2 ENDP
  182. ;STRFIND
  183. P3 PROC
  184. HINT MSG8
  185. GETCHAR
  186. NEWLINE
  187. MOV DI,OFFSET STR1+
  188. MOV CL,STR1+
  189. XOR CH,CH
  190. MOV AL,CHAR
  191. CLD
  192. REPNZ SCASB
  193. JZ FOUND
  194. HINT MSG10
  195. JMP P3_RETURN
  196. FOUND: HINT MSG9
  197. P3_RETURN:RET
  198. P3 ENDP
  199. ;SRTCMP+STRCAT+STRCPY
  200. P4 PROC
  201. MOV SI,OFFSET STR1+
  202. MOV DI,OFFSET STR2+
  203. CALL P1
  204. NEWLINE
  205. CMP AL,
  206. JNE LA41
  207. CALL P2
  208. JMP CONTINUE4
  209. LA41: CMP AL,
  210. JNE LA42
  211. CALL P2
  212. JMP CONTINUE4
  213. LA42: CMP AL,
  214. JNE CONTINUE4
  215. CALL P2_2
  216. CONTINUE4:
  217. RET
  218. P4 ENDP
  219.  
  220. SWITCH PROC
  221. CMP OP,
  222. JNE LA1
  223. MOV SI,OFFSET STR1+
  224. MOV DI,OFFSET STR2+
  225. CALL P1
  226. JMP CONTINUE
  227. LA1: CMP OP,
  228. JNE LA2
  229. CALL P2
  230. JMP CONTINUE
  231. LA2: CMP OP,
  232. JNE LA3
  233. CALL P3
  234. JMP CONTINUE
  235. LA3: CMP OP,
  236. JNE LAN
  237. CALL P4
  238. JMP CONTINUE
  239. LAN: HINT MSG3
  240. CONTINUE:RET
  241. SWITCH ENDP
  242.  
  243. MAIN PROC FAR
  244. MOV AX,DATA
  245. MOV DS,AX
  246. MOV ES,AX
  247.  
  248. ;input str1
  249. HINT MSG2
  250. CALL GETSTR1
  251. NEWLINE
  252. ;input str2
  253. HINT MSG3
  254. CALL GETSTR2
  255. NEWLINE
  256. ;input op
  257. HINT MSG1
  258. GETOP
  259. NEWLINE
  260. ;SWITCH OP
  261. CALL SWITCH
  262.  
  263. EXIT: MOV AX,4C00H
  264. INT 21H
  265. MAIN ENDP
  266.  
  267. CODE ENDS
  268. END MAIN

2-5 运行结果

2-5-1 操作类型为1,即比较str1和str2的字典序

2-5-2 操作类型为2,即将str2拼接到str1后,并将整个串拷贝至str3

2-5-3 操作类型为3,即再输入一个字符char,判断char是否属于str1

2-5-4 操作类型为4,即比较str1和str2的字典序按降序进行拼接,并拷贝到str3

显然,运行结果符合预期。

3 字符串按字典序排序

3-1 练习要点

  • 字符串的操作,LODSB,STOSB,CMPSB,REPE等等
  • 各个字符串操作指令对PSW和SI,DI的影响
  • 子程序调用与宏
  • 冒泡排序算法
  • 复杂程序的调试

3-2 重点难点

  • 冒泡排序
  • 宏和子程序的编写时必须注意堆栈的维护,用到的变量必须压栈处理
  • 字符串交换的逻辑
  • 操作字符串的子程序必须对SI,DI压栈保存,因为会隐式修改SI,DI

3-3 实现思路

  • 调用输出子程序输出原单词表
  • 调用排序子程序
  • 调用输出子程序输出排序后的单词表

3-4 代码实现

  • 输出子程序中每输出一个单词,就将SI增加STR_LEN,循环输出TABLE_LEN次
  • 排序子程序采用冒泡,在相邻两单词比较时,将当前单词置于DS:SI,相邻下一单词置于ES:DI,并比较其字典序,若当前单词字典序较大,则调用交换子程序,并将标志位BX置0,表示这一趟外层循环排序有调整。当一趟外层循环排序无调整,则表示当前单词表有序,即可退出排序子程序。
  • 比较子程序要注意对SI的维护,以及REPE CMPSB的含义:当CX≠0且ZF=1时执行CMPSB,CMPSB返回SI和DI的比较结果,并将二者分别+1,CX为提前计算好的两字符串的长度。含义是,当两字符串的前若干位字符相同时,就继续向后比较,直到比较到长度的结尾,或出现不同时结束。后接JA,JB指令,根据比较结果进行跳转与执行相关逻辑。
  • 交换S1,S2的逻辑:S1->TMP , S2->S1 , TMP->S2。
  1. STACK SEGMENT PARA STACK
  2. DW 100H DUP(?)
  3. STACK ENDS
  4.  
  5. DATA SEGMENT PARA
  6. TABLE_LEN EQU
  7. STR_LEN EQU
  8. TABLE DB 'QIQI',20H,,'$'
  9. DB 'CHEN',20H,,'$'
  10. DB 'XIAN',20H,,'$'
  11. DB 'QIQJ',20H,,'$'
  12. DB 'XHAN',20H,,'$'
  13. DB 'XIBN',20H,,'$'
  14. DB 'XHQI',20H,,'$'
  15. DB 'LOVE',20H,,'$'
  16. DB 'SURE',20H,,'$'
  17. TEMP DB STR_LEN DUP(?)
  18. NEW_LINE DB 0DH,0AH,'$'
  19. DATA ENDS
  20.  
  21. CODE SEGMENT PARA
  22. ASSUME CS:CODE,DS:DATA,SS:STACK
  23.  
  24. NEWLINE MACRO
  25. PUSH DX
  26. PUSH AX
  27. MOV DX,OFFSET NEW_LINE
  28. MOV AH,
  29. INT 21H
  30. POP AX
  31. POP DX
  32. ENDM
  33.  
  34. OUTPUT PROC
  35. PART1:
  36. MOV CX,TABLE_LEN
  37. MOV SI,OFFSET TABLE
  38. LP1:
  39. MOV DX,SI
  40. MOV AH,
  41. INT 21H
  42. ADD SI,STR_LEN
  43. LOOP LP1
  44. NEWLINE
  45. RET
  46. OUTPUT ENDP
  47.  
  48. COMP PROC
  49. COMPARE:
  50. PUSH SI
  51. PUSH CX
  52. CLD
  53. PUSH SI
  54. MOV CX,
  55. SLP1:
  56. LODSB
  57. CMP AL,00H
  58. JZ SLP1_1
  59. INC CX
  60. JMP SHORT SLP1
  61. SLP1_1:
  62. POP SI
  63. REPE CMPSB
  64. JA SL1
  65. JB SL2
  66. MOV AL, ;SI=DI
  67. JMP SHORT RETURN
  68. SL1:
  69. MOV AL, ;SI>DI
  70. JMP SHORT RETURN
  71. SL2:
  72. MOV AL, ;SI<DI
  73. RETURN:
  74. POP CX
  75. POP SI
  76. RET
  77. COMP ENDP
  78.  
  79. STRCPY PROC
  80. STRING_COPY:
  81. PUSH SI
  82. PUSH DI
  83. PUSH AX
  84. CLD
  85. CPY_LP1:
  86. LODSB
  87. STOSB
  88. CMP AL,
  89. JNZ CPY_LP1
  90. POP AX
  91. POP DI
  92. POP SI
  93. RET
  94. STRCPY ENDP
  95.  
  96. EXCHG PROC
  97. EXCHANGE:
  98. PUSH SI
  99. PUSH DI
  100.  
  101. MOV DI,OFFSET TEMP
  102. CALL STRCPY
  103.  
  104. MOV DI,SI
  105. ADD SI,STR_LEN
  106. CALL STRCPY
  107.  
  108. MOV DI,SI
  109. MOV SI,OFFSET TEMP
  110. CALL STRCPY
  111. POP DI
  112. POP SI
  113. RET
  114. EXCHG ENDP
  115.  
  116. SORT PROC
  117. PART2:
  118. MOV CX,TABLE_LEN
  119. DEC CX
  120. LP2:
  121. MOV BX,
  122. MOV SI,OFFSET TABLE
  123. PUSH CX
  124.  
  125. LP2_1:
  126. MOV AX,SI
  127. ADD AX,STR_LEN
  128. MOV DI,AX
  129. CALL COMP
  130. CMP AL,
  131. JBE CONTINUE
  132. CALL EXCHG
  133. MOV BX,
  134. CONTINUE:
  135. ADD SI,STR_LEN
  136. LOOP LP2_1
  137.  
  138. POP CX
  139. DEC CX
  140. CMP BX,
  141. JZ SORT_RETURN
  142. JMP SHORT LP2
  143. SORT_RETURN:
  144. RET
  145. SORT ENDP
  146.  
  147. MAIN PROC FAR
  148. MAIN_PART:
  149. MOV AX,DATA
  150. MOV DS,AX
  151. MOV ES,AX
  152. ;DISPLAY ORIGIN TABLE
  153. CALL OUTPUT
  154. ;SORT
  155. CALL SORT
  156. ;DISPLAY ORDERED TABLE
  157. CALL OUTPUT
  158.  
  159. EXIT:
  160. MOV AX,4C00H
  161. INT 21H
  162. MAIN ENDP
  163.  
  164. CODE ENDS
  165. END MAIN

3-5 运行结果

在DATA段预置字典如下图所示

编译、链接并执行程序,得到结果如下,第一行为元单词表,第二行为排序后的单词表(按字典序升序)

显然,运行结果符合预期。

x86汇编语言实践(2)的更多相关文章

  1. x86汇编语言实践(3)

    0 写在前面 为了更深入的了解程序的实现原理,近期我学习了IBM-PC相关原理,并手工编写了一些x86汇编程序. 在2017年的计算机组成原理中,曾对MIPS体系结构及其汇编语言有过一定的了解,考虑到 ...

  2. x86汇编语言实践(1)

    0 写在前面 为了更深入的了解程序的实现原理,近期我学习了IBM-PC相关原理,并手工编写了一些x86汇编程序. 在2017年的计算机组成原理中,曾对MIPS体系结构及其汇编语言有过一定的了解,考虑到 ...

  3. 进入保护模式(三)——《x86汇编语言:从实模式到保护模式》读书笔记17

    (十)保护模式下的栈 ;以下用简单的示例来帮助阐述32位保护模式下的堆栈操作 mov cx,00000000000_11_000B ;加载堆栈段选择子 mov ss,cx mov esp,0x7c00 ...

  4. VS2013的x86汇编语言开发环境配置

    转载:https://blog.csdn.net/infoworld/article/details/45085415 转载:https://blog.csdn.net/u014792304/arti ...

  5. 存储器的保护(三)——《x86汇编语言:从实模式到保护模式》读书笔记20

    存储器的保护(三) 修改本章代码清单,使之可以检测1MB以上的内存空间(从地址0x0010_0000开始,不考虑高速缓存的影响).要求:对内存的读写按双字的长度进行,并在检测的同时显示已检测的内存数量 ...

  6. 存储器的保护(一)——《x86汇编语言:从实模式到保护模式》读书笔记18

    本文是原书第12章的学习笔记. 说句题外话,这篇博文是补写的,因为让我误删了,可恶的是CSDN的回收站里找不到! 好吧,那就再写一遍,我有坚强的意志.司马迁曰:“文王拘而演<周易>:仲尼厄 ...

  7. 16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16

    一.Intel 32 位处理器的工作模式 如上图所示,Intel 32 位处理器有3种工作模式. (1)实模式:工作方式相当于一个8086 (2)保护模式:提供支持多任务环境的工作方式,建立保护机制 ...

  8. 进入保护模式(二)——《x86汇编语言:从实模式到保护模式》读书笔记14

    首先来段题外话:之前我发现我贴出的代码都没有行号,给讲解带来不便.所以从现在起,我要给代码加上行号.我写博客用的这个插入代码的插件,确实不支持自动插入行号.我真的没有找到什么好方法,无奈之下,只能按照 ...

  9. linux平台学x86汇编语言学习集合帖

    linux平台学x86汇编语言学习集合帖 linux平台学x86汇编(一):https://blog.csdn.net/shallnet/article/details/45543237 linux平 ...

随机推荐

  1. MySQL InnoDB 存储引擎探秘

    在MySQL中InnoDB属于存储引擎层,并以插件的形式集成在数据库中.从MySQL5.5.8开始,InnoDB成为其默认的存储引擎.InnoDB存储引擎支持事务.其设计目标主要是面向OLTP的应用, ...

  2. spring cloud feign 文件上传和文件下载

    文件上传参考文档:http://blog.didispace.com/spring-cloud-starter-dalston-2-4/ 文件下载参考文档:https://blog.csdn.net/ ...

  3. Openlayer 3加载本地ArcGIS切片

    第一篇博客,简单的开个头吧.希望自己能坚持记录.一般什么情况什么人需要这样的需求呢,伐木的光头强大哥说我们在深山老林里,没网的啊,地图就手机本地duang的加载一下吧.那么Server啊就要丢掉丢掉. ...

  4. 如何快速清理 docker 资源

    如果经常使用 docker,你会发现 docker 占用的资源膨胀很快,其中最明显也最容易被察觉的应该是对磁盘空间的占用.本文将介绍如何快速的清理 docker 占用的系统资源,具体点说就是删除那些无 ...

  5. JMeter 接口测试-if控制器

    JMeter 接口测试-if控制器 ​ 使用场景: 当业务场景是用户登录才能支付操作, 不登录点击支付, 页面会跳转到登录页面. 对于接口也是这样, 一个接口需要执行前, 需要有前提条件, 比如0状态 ...

  6. 测者的测试技术手册:智能化测试框架EvoSuite的一个坑以及填坑方法

    问题 最近在不断地学习和探索EvoSuite框架的时候,在生产JUnit单元测试框架后,出现如下问题: Exception: Caused by: org.evosuite.runtime.TooMa ...

  7. hbase snapshot 表备份/恢复

    snapshot其实就是一组metadata信息的集合,它可以让管理员将表恢复到以前的一个状态.snapshot并不是一份拷贝,它只是一个文件名的列表,并不拷贝数据.一个全的snapshot恢复以为着 ...

  8. oracle相关函数

    (大写的PS:oracle存储过程测试进不去解决方案:重新编译:) TRUNC(sysdate, 'd') + 1   ////表示今天所在周的周一的年月日,如今天是2016.04.21周四,则TRU ...

  9. Web前端教程-HTML及标签的使用

    目录 1. HTML简介 1.1. HTML文档基本结构 2. 标签 2.1. 标签语法 1.2. 标签的属性和值 1.3. 常见的标签 1. 基础标签 2. 格式标签 3. 表单标签 4. 框架标签 ...

  10. 浏览器中 F12 功能的简单介绍

    chrome浏览器中 F12 功能的简单介绍 由于F12是前端开发人员的利器,所以我自己也在不断摸索中,查看一些博客和资料后,自己总结了一下来帮助自己理解和记忆,也希望能帮到有需要的小伙伴,嘿嘿! 首 ...