x86 汇编入门(03):算术运算与数字转字符串
终端只能显示字符,不能直接显示数字 42。所以汇编里做算术只是第一步,更麻烦的是把结果「翻译」成 '4' 和 '2' 再送出去。这一篇我们练四则运算,并实现一个可复用的 print_number 子程序。
这是「x86 汇编入门」系列的第 3 篇。前两篇解决了输出字符串和读取输入。这一篇通过
03_calc.asm,掌握算术指令和整数转 ASCII 的核心技巧。
一、基本算术指令
对两个常数 42 和 8 演示四则运算:
| 指令 | 含义 | 示例结果 |
|---|---|---|
add dst, src |
加法 | 42 + 8 = 50 |
sub dst, src |
减法 | 42 - 8 = 34 |
imul dst, src |
有符号乘法 | 42 × 8 = 336 |
idiv src |
有符号除法 | 42 ÷ 8 = 5 … 2 |
除法要特别注意:idiv 用 rdx:rax 作为被除数。执行前需要 cqo 把 rax 符号扩展到 rdx:
1 | mov rax, num_a |
二、程序结构:主流程 + 子程序
03_calc.asm 比前两篇多了函数雏形。主程序依次打印五组结果:
1 | mov rsi, msg_add |
call 跳转到子程序,执行完 ret 回到下一条指令——下一篇会深入讲机制,这里先当「可复用的代码块」用。
三、数字转字符串的原理
人看 50,机器里是二进制。要打印出来,经典做法是反复除以 10:
50 ÷ 10→ 商 5,余 0 → 字符'0'5 ÷ 10→ 商 0,余 5 → 字符'5'- 余数从低到高入栈,再倒序弹出输出 →
"50"
核心循环:
1 | .divide_loop: |
'0' 的 ASCII 码是 48,所以余数 0–9 加上 '0' 就得到 '0'–'9'。
四、运行输出
1 | make |
1 | 42 + 8 = 50 |
五、工程上的小细节
- 除法后余数在
rdx,调用print_number前用push rdx保存,避免被覆盖 print_str约定:rsi= 地址,rdx= 长度——类似精简版调用约定num_str放在.bss,作为逐字符输出的临时缓冲
六、小结
本篇你掌握了:
add/sub/imul/idiv与cqo的配合- 除法取商和余数
- 整数转十进制字符串的「除 10 取余 + 倒序输出」算法
- 用
call/ret组织可复用代码(预告下一篇)
x86 汇编入门系列第 3 篇完。下一篇用条件跳转和循环,让程序重复执行——打印 1 到 10。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 WALL-E`s Blog!







