- 主题:DOS 写汇编最烦的地方是调函数保存寄存器吧
现代的risc汇编就不适合让人手写吧, 写小段的关键代码可能还凑和, 大段写下来大概率不如机器.
以前x86汇编相对还是比较适合手写的
【 在 blackoil 的大作中提到: 】
手工制作,跟工厂量产的区别。
【 在 hgoldfish 的大作中提到: 】
: 和现代编译器的寄存器分配算法有啥区别吗?
:
--
FROM 124.16.158.*
主要是改动麻烦,规模大了,几乎不可能全手写汇编实现。
【 在 tom6bj 的大作中提到: 】
: 现代的risc汇编就不适合让人手写吧, 写小段的关键代码可能还凑和, 大段写下来大概率不如机器.
: 以前x86汇编相对还是比较适合手写的
: 手工制作,跟工厂量产的区别。
: ...................
--
FROM 219.137.49.*
除了一些编译后端不支持的特殊流水线优化等极端情况,手写汇编对于较大程序,性能没有明显优势。
写的还慢,代码长也容易出错。
【 在 blackoil 的大作中提到: 】
:
: 主要是改动麻烦,规模大了,几乎不可能全手写汇编实现。
:
: 【 在 tom6bj 的大作中提到: 】
: : 现代的risc汇编就不适合让人手写吧, 写小段的关键代码可能还凑和, 大段写下来大概率不如机器.
#发自zSMTH@如有雷同 纯属巧合
--
FROM 123.122.162.*
今天闲得没事继续想这个寄存器的事情。
不管 DOS 程序使用寄存器传参还是使用栈。在调用其它函数之前,如果不知道被调用函数是否使用寄存器,那调用者最好先把寄存器保存一下。既然是这样,那完全可以多用 fastcall 寄存器传参啊。
神奇的是为啥当年在 DOS 下 c 语言会选择那个 cdecl 调用约定。难道是只是为了实现 printf() ?
那么保存寄存器的时候,用 PUSHA 方便呢?还是一个个 PUSH 比较方便?可惜 PUSHA 是 80186 的指令,8086 不能用。
【 在 hgoldfish 的大作中提到: 】
: 每调一个函数都需要把自己使用到的寄存器保存到栈上,再调用函数。等函数返回后,还得把寄存器一个个从栈上弹出来。
: 这个开销挺大的,所以听说以前有个技巧是写超大的 main() 函数. 以减少函数的调用开销?
--
FROM 110.84.122.*
【 在 hgoldfish 的大作中提到: 】
: 标 题: Re: DOS 写汇编最烦的地方是调函数保存寄存器吧
: 发信站: 水木社区 (Thu Oct 3 16:45:57 2024), 站内
:
: 今天闲得没事继续想这个寄存器的事情。
:
: 不管 DOS 程序使用寄存器传参还是使用栈。在调用其它函数之前,如果不知道被调用函数是否使用寄存器,那调用者最好先把寄存器保存一下。既然是这样,那完全可以多用 fastcall 寄存器传参啊。
没有看过这方面的历史,我猜还是因为当时的指令集对寄存器的使用不够general,很多指令都只能使用特定的寄存器,你用了寄存器传餐了,后面要用的时候不在你期待的寄存器里怎么办,还得挪到特定的寄存器中,有时还需要把某些寄存器先压栈。。。
:
: 神奇的是为啥当年在 DOS 下 c 语言会选择那个 cdecl 调用约定。难道是只是为了实现 printf() ?
你想说的是vararg吧,用寄存器传参也能实现的,参考现代的调用约定
:
: 那么保存寄存器的时候,用 PUSHA 方便呢?还是一个个 PUSH 比较方便?可惜 PUSHA 是 80186 的指令,8086 不能用。
当然用pusha更方便了,但是不是每一个寄存器都需要保存的,取决于你的函数实际用了多少寄存器吧
:
: 【 在 hgoldfish 的大作中提到: 】
: : 每调一个函数都需要把自己使用到的寄存器保存到栈上,再调用函数。等函数返回后,还得把寄存器一个个从栈上弹出来。
: : 这个开销挺大的,所以听说以前有个技巧是写超大的 main() 函数. 以减少函数的调用开销?
:
: --
: 灭绝人性啊
:
:
: ※ 来源:·水木社区 mysmth.net·[FROM: 110.84.122.*]
--
FROM 73.202.29.*
i386 的一些调用约定 (c, borland register, stdcall) 有要求函数保存 EAX, ECX, EDX. 其它的 EBX, ESI, EDI, EBP, ESP 这几个,如果被调用者要用到的话,需要自行保存。
个人感觉 borland register 的调用约定是比较合理的。其它的调用约定简直是丧心病狂也不知是怎么想出来的。既要求调用者保存 EAX, ECX, EDX 又不拿来传参数。这不是浪费宝贵的字节么。
8086 的话,也是 turbo c 比较合理,使用了 AX, DX, BX 进行传参。
【 在 BigCarrot 的大作中提到: 】
: 没有看过这方面的历史,我猜还是因为当时的指令集对寄存器的使用不够general,很多指令都只能使用特定的寄存器,你用了寄存器传餐了,后面要用的时候不在你期待的寄存器里怎么办,还得挪到特定的寄存器中,有时还需要把某些寄存器先压栈。。。
: 你想说的是vararg吧,用寄存器传参也能实现的,参考现代的调用约定
: 当然用pusha更方便了,但是不是每一个寄存器都需要保存的,取决于你的函数实际用了多少寄存器吧
: ...................
--
修改:hgoldfish FROM 110.84.122.*
FROM 110.84.122.*
386对寄存器的使用已经非常通用了
当时的调用约定你要放在当时的情况下去理解它的合理性
不过现在研究这个已经完全没有意义了
你有时间不如研究研究现在的调用约定,看看还有什么提高的地方
比如说apx马上就出来了,x86也能有32个通用寄存器了,sys v abi对这16个新寄存器只能用作callee saved register,其他没有任何改变。我觉得肯定有更好的分配方法。
【 在 hgoldfish 的大作中提到: 】
: i386 的一些调用约定 (c, borland register, stdcall) 有要求函数保存 EAX, ECX, EDX. 其它的 EBX, ESI, EDI, EBP, ESP 这几个,如果被调用者要用到的话,需要自行保存。
: 个人感觉 borland register 的调用约定是比较合理的。其它的调用约定简直是丧心病狂也不知是怎么想出来的。既要求调用者保存 EAX, ECX, EDX 又不拿来传参数。这不是浪费宝贵的字节么。
: 8086 的话,也是 turbo c 比较合理,使用了 AX, DX, BX 进行传参。
: ...................
--
FROM 73.202.29.*
都玩 DOS 了,肯定不是冲着实用性去的。
我经常在思考的一个问题。用现在的软件思维在当年受限的硬件上面重写当年的软件能不能做到更快更好?如果不行,那我们的软件工业算是进步了吗?
【 在 BigCarrot 的大作中提到: 】
: 386对寄存器的使用已经非常通用了
: 当时的调用约定你要放在当时的情况下去理解它的合理性
: 不过现在研究这个已经完全没有意义了
: ...................
--
FROM 59.61.197.*
我恰恰相反,如果按现在的应用重新设计机器会怎么样
比如现在就缺了复合类型的操作
双重指针操作的优化也没有
【 在 hgoldfish 的大作中提到: 】
: 都玩 DOS 了,肯定不是冲着实用性去的。
: 我经常在思考的一个问题。用现在的软件思维在当年受限的硬件上面重写当年的软件能不能做到更快更好?如果不行,那我们的软件工业算是进步了吗?
--
FROM 112.66.26.*
这是硬件设计啊。或许你对 riscv 会感兴趣哈哈。
可惜龙芯的 la64 没有把 mips 的包袱多抛一些。有点不上不下的。
【 在 chaobill 的大作中提到: 】
: 我恰恰相反,如果按现在的应用重新设计机器会怎么样
: 比如现在就缺了复合类型的操作
: 双重指针操作的优化也没有
: ...................
--
FROM 59.61.197.*