看上去是汇编新人,欢迎新人。然后是一些小建议和知识。
首先是源码方面,代码建议加代码标签,就是发帖工具栏里那个#号,加了跟不加的区别是这样的。
-----
我是代码
-----
-----
我是代码
-----
后一种方便其他人阅读复制等,也不会因为论坛的一些问题破坏格式。
然后是汇编代码部分。
.386
.model flat,stdcall
option casemap:none
include user32.inc
includelib user32.lib
这一部分,可以替换成一句
include masm32rt.inc
masm32中提供了masm32rt这个头文件,里面就是汇编开头这几句固定的内容和include常用的库。虽然这个头文件有时候可能需要自己修改一下,里面的相对路径有时候会出问题。但是搞定后以后就可以只用这一句了,很方便。
.data
a dd -10000000;-10000000这是1秒,-20000000是2秒
s dd -1
变量命名建议有意义一点,尤其是这种全局变量。不然程序写大了以后根本分不清哪个是哪个,这是一个习惯问题。比如可以用
《匈牙利命名法》。
http://zh.wikipedia.org/wiki/%E5%8C%88%E7%89%99%E5%88%A9%E5%91%BD%E5%90%8D%E6%B3%95
.code
start:
push offset a
push 0
push aa
push aa
mov eax,3bh
mov edx,esp
db 0fh
db 34h;sysenter
sysenter无法直接写出来的原因是因为你最上面的定义是.386,在386指令集中是没有sysenter的,改成.686即可。
另外,masm32rt.inc里的定义是.486,不过像下面这种写法是没问题的。
include masm32rt.inc
.686
aa:
pop eax
invoke MessageBoxA,0,0,0,0
调用api时参数要写明确,不然程序大了后可读性也很受影响。这也是编程习惯问题。
正确写法
invoke MessageBox,NULL,NULL,NULL,MB_OK
虽然实际上常量对应的值都是0,但是这样对人类阅读更友好。
比如说 我如果最后一个值写的是33,你真的能知道窗口风格是 yes按钮和no按钮,并且带有一个问号图标么。
而写作下面这样,就可以一目了然了,虽然英文对国人也不是很容易理解,但至少比数字要好。
这些常量的值可以在对应api的msdn找到。
invoke MessageBox,NULL,NULL,NULL,MB_YESNO+MB_ICONQUESTION
---------------------------
leave
ret
end start
在这里,leave是不必要的,甚至是会引起错误的。程序最后一句为end start,含义为<本程序的代码到此为止 全程序的开始起点是start>。而leave是要对应一句enter或者push ebp&mov ebp,esp的,而start那里并没有。
---------------------------
其他问题
这种sysenter的调用其实就是直接调用ssdt表函数,所以在不同版本下兼容性是很差的,比如在xp中是3bh,但是在windows2003上你调用的应该是3dh,vista上应该是75h……以及其他新的系统中大部分都不一样。所以正常的软件开发中要
极力避免出现类似这样的代码。
对应的编号在这里可以查到,但是就算是有了所有的编号,也不要用这种方式来写代码,因为以后的系统补丁可能会
更改这些编号。
http://j00ru.vexillium.org/ntapi/(需要点击一下show all才能显示)