代码改变世界

masm

2012-12-15 11:01  robturtle  阅读(790)  评论(0编辑  收藏  举报

dos 例程调用(int 21h)

0a 调用:从标准输入获得字符串,遇到换行符(0a)结束,而Enter键中输入的(0d0a)中的回车符将保存在字符串中,如果不注意的话,可能会产生很奇怪的输出。

bug:

dosemu 和 vim 的paste不兼容,正常敲进去的代码在dosemu下也正常,但如果用p命令粘贴过去的则会吃掉所有的回车。

堆栈:

堆栈的使用要相当小心,弹/压顺序错误,多弹/压或少弹/压都可能导致程序直接崩溃。这句话中,关键的是在于少弹也会搞崩这点,考虑函数调用的情形就很清楚了,少弹的结果直接导致错误的cs和ip。

Error: Phase error between passes

如果在代码段后面定义函数,而代码段上面又有个label的话就会报,还没搞懂为什么会报错。不过只要把定义放到前面就ok了。听说masm高版本就没这个问题。

宏与函数

对于现代汇编,有一个概念必须明确:汇编语言是一种高级语言,你可以把汇编语言理解成可以操作寄存器的c语言。

正因为此,出于练习的目的,我才没有选择那些fancy的特性,而是用基本的指令组合实现控制,然后自己造车轮——把基本的控制指令组合编写成宏。

masm5.0的语法中,调用函数很占地方,于是我用宏封装了函数,这样压入参数,调用函数的过程就简化为一行带参宏语言了。然后我自己仿照c的命名规则,给函数命名为 _foo,而宏命名为foo。

一般情况下函数调用可以直接使用宏,但是如果调用上下文中没有宏需要的信息,还是需要调用原始的函数。

NOTE:调用宏的语法为 foo [arg1, arg2…], 而如果误写成函数的调用语句 call far ptr foo, 汇编器并不会报错!但是它将因为找不到入口点,而把这个语句翻译成: CALL 0000:0000! What the fuck!

[12/12/19] 和上面宏/函数误用类似的,如果函数声明为near,而使用call far ptr,也不会有任何错误或警告信息。这时候,调用的时候会压入段和偏移,弹出的时候则只会弹出偏移,堆栈错误也就发生了。对于手写代码的一个好的建议就是,所有的函数都声明为far。这样一来,near类型除了会诱发各种错误外就看不到任何的优点了。这就是masm5.0。