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。