汇编中add '0'与sub '0'的作用及相关代码片段疑问咨询
解析x86汇编中的
sub eax, '0'与add eax, '0' 先来看你提供的完整汇编代码:
section .text global _start ;must be declared for using gcc _start: ;tell linker entry point mov eax,'3' sub eax, '0' mov ebx, '4' sub ebx, '0' add eax, ebx add eax, '0' mov [sum], eax mov ecx,msg mov edx, len mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov ecx,sum mov edx, 1 mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel section .data msg db "The sum is:", 0xA,0xD len equ $ - msg segment .bss sum resb 1
针对你疑问的三行代码拆解
首先得明确ASCII编码规则:在ASCII表中,字符'0'的十进制值是48,'3'是51,'4'是52,'7'是55,而且所有数字字符是连续排列的。
sub eax, '0'
前面的mov eax,'3'是把字符'3'的ASCII值(51)加载到eax寄存器里。这行代码执行的是51 - 48 = 3,把字符形式的数字转换成了对应的整数数值——毕竟寄存器里存的ASCII值直接相加的话,结果会是51+52=103,这可不是我们要的3+4=7。sub ebx, '0'
和上面逻辑完全一致:mov ebx,'4'把'4'的ASCII值(52)放进ebx,减去'0'的ASCII值(48)后,ebx里就变成了整数4,准备好参与加法运算。add eax, '0'
前面的add eax, ebx已经算出了整数7(3+4),但我们最终要通过sys_write输出结果,而sys_write输出的是ASCII字符,不是整数。这行代码执行的是7 + 48 = 55,正好是字符'7'的ASCII值,把整数数值转换回了可显示的字符形式,这样后续输出才能显示出正确的数字。
汇编中add '0'和sub '0'的通用意义
这是汇编里处理数字字符与整数转换的经典技巧:
sub 寄存器, '0':将'0'到'9'的ASCII字符转换为0到9的整数,利用ASCII表中数字字符连续排列的特性,直接做减法就能得到对应的数值。add 寄存器, '0':将0到9的整数转换为对应的ASCII字符,同样利用连续编码的特性,加上'0'的ASCII值就能得到可显示的数字字符编码。
内容的提问来源于stack exchange,提问作者Роман
相关产品推荐
相关产品推荐

