CF93C Azembler

题目描述

在“Search Ultimate”程序因在文本中查找字符串时失败后,Igor K. 开始思考:“为什么我的程序这么慢?”在他仔细检查自己的代码后,说道:“我的代码没有错误,但我知道怎么让 Search Ultimate 更快!”于是他从书架上取下一本大书。封面写着《Azembler. Principally New Approach》。 Igor K. 仔细翻阅了这本书后明白了,原来你可以让乘法执行得快几十倍。“Search Ultimate 会比以往任何时候都更快!”——他高兴地叫道,并开始着手工作。 现在让我们澄清一下 Igor 的想法。问题在于编译器生成的代码远非完美。标准乘法的运行速度比书中提及的技巧慢得多。 Azembler 语言有 26 个寄存器(eax, ebx, ..., ezx)和两条指令: - \[ $x$ \] — 返回位于地址 $x$ 的数值。例如,\[eax\] 返回存放在地址 eax 的数值。 - lea $x$ , $y$ — 把第二个参数 $y$ 的地址赋给第一个参数 $x$ 所指的寄存器。例如,“lea ebx, \[eax\]” 指令,将 eax 寄存器中的内容写入 ebx:首先执行 \[eax\] 操作,其结果是位于 eax 寄存器所存地址的某个值。但事实上我们并不需要这个值——下一步是 lea 操作,它会把 \[eax\] 的地址(即 eax 中的值)写入 ebx。 乍一看,第二种操作似乎毫无意义,但事实上可以写成: lea ecx, \[eax + ebx\], lea ecx, \[k\*eax\], 甚至 lea ecx, \[ebx + k\*eax\], 其中 $k$ 只能是 1、2、4 或 8。 最终,ecx 寄存器的值分别为 eax + ebx、k\*eax 和 ebx + k\*eax。然而,这样的操作执行速度要比通常的数值乘法快很多倍。通过使用若干此类操作,可以非常迅速地实现某个数乘以另一个数。当然,eax、ebx、ecx 都可以任意替换成其它寄存器。 例如,假设 eax 寄存器中有一个数,我们要将它乘以 41。这只需要 2 行指令: lea ebx, \[eax + 4\*eax\] // 此时 ebx = 5\*eax lea eax, \[eax + 8\*ebx\] // 此时 eax = eax + 8\*ebx = 41\*eax Igor K. 感兴趣的问题是:最少需要多少条 lea 操作才能实现乘以给定的数 $n$?应该如何实现?你的任务就是帮助他解决这个问题。 初始时,eax 内存放待乘以 $n$ 的数,ebx 到 ezx 的所有寄存器的内容均为 0。最终,结果可以存放在任意寄存器中。

输入格式

输入包含唯一一个整数 $n$($1 \leq n \leq 255$),即 Igor K. 要实现的乘数。

输出格式

第一行输出最少需要的 lea 操作数 $p$。接下来的 $p$ 行输出该程序的 $p$ 条指令。 要求严格使用以下格式的指令输出(其中 $k$ 取 1、2、4、8,$x$、$y$、$z$ 为任意寄存器,允许取相同寄存器名): lea x, \[y\] lea x, \[y + z\] lea x, \[k\*y\] lea x, \[y + k\*z\] 注意命令行末不得有多余的空格。

说明/提示

由 ChatGPT 5 翻译