汇编程序员之代码风格指南
来源:互联网 发布:淘宝睡眠水 编辑:程序博客网 时间:2024/05/18 04:21
©CVC电脑病毒论坛 -- 中国毒客的快乐天地 4
作者:Randall HydebxLj
http://webster.cs.ucr.edu/
节选1.0 和 1.1:
1.0简介
许多人认为汇编程序难于阅读。虽然大家有这种感觉有许多原因,但最主要的还是汇编语言难以使得程序员写出易读的程序。这并不表示不可能编写出易读的程序,只是它要花费汇编程序员一部分额外的工作来写出易读代码。
为了示范汇编程序的一些公共问题,决定使用下面的程序或程序段。这些都是在Internet上找到的真正用汇编语言编写的程序。每个例子都示范了一个单独的问题。(顺便一提:选择这些程序并不是有意让原作者难吭。这些程序都是在网上找到的汇编代码特例)。
代码:
1.1ADDHEX.ASM
%title "两个16进制数相加"
IDEAL
DOSSEG
MODEL small
STACK 256
DATASEG
exitCode db 0
prompt1 db 'Enter value 1: ', 0
prompt2 db 'Enter value 2: ', 0
string db 20 DUP (?)
CODESEG
EXTRN StrLength:proc
EXTRN StrWrite:proc, StrRead:proc, NewLine:proc
EXTRN AscToBin:proc, BinToAscHex:proc
Start:
mov ax,@data
mov ds,ax
mov es,ax
mov di, offset prompt1
call Getvalue
push ax
mov di, offset prompt2
call Getvalue
pop bx
add ax,bx
mov cx,4
mov di, offset string
call BinToAscHex
call StrWrite
Exit:
mov ah,04Ch
mov al,[exitCode]
int 21h
PROC Getvalue
call StrWrite
mov di, offset string
mov cl,4
call StrRead
call NewLine
call StrLength
mov bx,cx
mov [word bx + di], 'h'
call AscToBin
ret
ENDP Getvalue
END Start
好了,这个程序的最大问题还是相当明显的-除了标题之外完全没有其它注释(译注:国内有太多这样没注释的程序了)。另一个实际的问题则是用来提示用户的字符串出现在程序的一端但用来打印这些字符串的调用代码却出现在另外一个地方(译注:即指代码中的StrWrite等三个函数)。尽管这是个经典的汇编语言编程方法,但却导致了代码难于阅读。另外,相对次要的一个问题是该程序使用了TASM的 “less-than”IDEAL
语法(注:一些一直使用TASM的人会认为这没什么不好。但个别人就不这么认为了,由于他们不熟悉TASM的古怪语言,有时会导致被程序中的几条语句搞混淆)
这个程序也使用了MASM/TASM的“简单化”段定义。微软声称的这个典型特性却给一个“简单”的工程增加了复杂性。如果该程序转换为标准的段定义格式将会更加易读。
(注:使用简单段定义虽然更容易编写高级语言接口的汇编程序,但无论如何,他们都只会使单一的程序问题变得复杂)
在扔掉它之前,该程序还是有两点值得称赞的(遵循了可读性)。第一,该程序员为过程名和本程序使用的变量选择了一组合理的名称(我假定这段代码的作者同时也是该程序调用的库的作者)。程序另一个值得肯定的是助记性好和操作数之间有良好的对齐。
OK,在抱怨这份代码如何难读后,为什么不来个更易读的版本?下面的程序便是,可证明,该版本比上面的版本更加易读。可证明,因为该版本使用了UCR标准库v2.O
并假定读者熟悉该库的细节和特性。
代码:
;**************************************************
;
; AddHex-
;
; 这个简单的程序从用户那里获取两个整数值,计算它们的和,
; 并在屏幕上打印结果。
;
; 这个例子使用了“80x86汇编程序员的UCR标准库v2.0”
;
; Randall Hyde
; 12/13/96
title AddHex
.xlist
include ucrlib.a
includelib ucrlib.lib
.list
cseg segment para public 'code'
assume cs:cseg
; GetInt-
;
; 这个函数从键盘读取一个整数并将结果返回到AX寄存器中
;
; 该程序捕获无效的值(太大或无效数字)并需要用户重新输入一个数值。
;
GetInt textequ <call GetInt_p>
GetInt_p proc
push dx ;DX 保存错误代码
GetIntLoop: mov dx, false ;假定没错误
try ;捕获任何可能的错误
FlushGetc ;清空输入来换新行
geti ;读入整数值
except $Conversion ;捕获错误字符
print "Illegal numeric conversion, please re-enter", nl
mov dx, true
except $Overflow ;捕获数值太大
print "value out of range, please re-enter.",nl
mov dx, true
endtry
cmp dx, true
je GetIntLoop
pop dx
ret
GetInt_p endp
Main proc
InitExcept
print 'Enter value 1: '
GetInt
mov bx, ax
print 'Enter value 2: '
GetInt
print cr, lf, 'The sum of the two values is '
add ax, bx
puti
putcr
Quit: CleanUpEx
ExitPgm ;退出程序的DOS宏
Main endp
cseg ends
sseg segment para stack 'stack'
stk db 256 dup (?)
sseg ends
zzzzzzseg segment para public 'zzzzzz'
LastBytes db 16 dup (?)
zzzzzzseg ends
end Main
这里要特别指出的是这份代码比原来的那个AddHex程序要大一点。在细节上,它验证用户的输入;而在原程序上并没有这么做。如果那位想更严密地模范原程序,下面的简单代码即是:
代码:
print nl, 'Enter value 1: '
Geti
mov bx, ax
print nl, 'Enter value 2: '
Geti
add ax, bx
putcr
puti
putcr
在这个例子中,两个简单的解决方案改良了程序的可读性:增加注释、将程序格式化得更好点,而且使用了UCR标准库的高级特性来使得编码更为简单并使得打印输出字符串的语句保持它们的字面意思。
- 汇编程序员之代码风格指南
- 汇编程序员之代码风格指南
- 汇编程序员之代码风格指南
- Mozilla代码风格指南
- Android 代码风格指南
- Python代码风格指南
- Android 代码风格指南
- JavaScript 代码风格指南
- JavaScript 代码风格指南
- Python 代码风格---指南
- JavaScript 代码风格指南
- PEP8代码风格指南
- Python 代码风格指南
- javascript 代码风格指南
- Google C++编程风格指南之代码注释
- Google C++编程风格指南之代码注释
- GNU风格 ARM汇编语法指南
- GNU风格 ARM汇编语法指南
- java 栈,队列,链表,双链表,树
- Windows网络编程-(完成端口及网络编程)详细介绍1
- 浅聊一卡多号的好处
- 开编第一章
- java 查找算法
- 汇编程序员之代码风格指南
- DotNetBar 6.6.0.2 for VS2003
- Windows网络编程-(完成端口及网络编程)详细介绍2
- 怎样用ntdsutil删除ad中的垃圾信息
- SIM基本常识(PIN,PUK,IMEI,ICCID,Ki,IMSI,SMSP之间的区别)
- 帮助客户成功!最应该让客户知道他需要什么!
- 验证你的浏览器的信息
- Linux TCP/IP协议栈笔记
- 一卡多号基础性问题解答