NASM中.data段常量与.bss段用户输入双字比较失败求助
NASM输入与常量比较失败的问题解决
核心问题分析与修正步骤
- 比较指令的致命错误
你写的cmp dword [input], porovnat完全搞错了比较对象:porovnat是.data段变量的内存地址,而不是它存储的实际值。正确的写法应该是直接比较两个双字的内容:
cmp dword [input], dword [porovnat]
原来的指令是把输入内容和变量地址做对比,自然永远不会相等。
- 长度不匹配+内存溢出问题
- 用
dd 'start'声明porovnat时,dd是4字节双字类型,'start'是5个字符,NASM会自动截断为前4个字符:'s','t','a','r'。 - 你设置
read系统调用的edx=5,会读取5个字节。当输入start并回车,实际读入的是's','t','a','r','\n'(换行符ASCII码为0Ah),但input只通过resd 1保留了4字节空间,这会导致内存溢出,同时读入的内容和porovnat的4字节内容完全不匹配。
- 换行符的影响
终端输入时按下回车,确实会向输入流中添加换行符。如果要匹配start字符串,有两种处理方式:
- 只读取4字节(设置
edx=4),获取不带换行符的's','t','a','r',和porovnat的内容对齐; - 把
porovnat定义为包含换行符的5字节字符串,同时给input分配足够空间,用字符串比较指令完成匹配。
修正后的示例代码(匹配4字节输入)
SECTION .data zprava db 'ahoj',0Ah porovnat dd 'star' ; 明确存储4个字符,对应输入的前4位 SECTION .bss input resd 1 ; 4字节空间足够存储读取内容 SECTION .text global _start _start: ; 读取4字节,不包含换行符 mov edx,4 mov ecx,input mov ebx,0 mov eax,3 int 80h ; 正确比较两个双字的内容 cmp dword [input], dword [porovnat] jz dal jnz konec dal: mov edx,5 ;4个字符+换行符 mov ecx,zprava mov ebx,1 mov eax,4 int 80h jmp konec konec: mov ebx,0 mov eax,1 int 80h
另一种方案(匹配带换行符的完整输入)
SECTION .data zprava db 'ahoj',0Ah porovnat db 'start',0Ah ; 定义包含换行符的5字节目标字符串 SECTION .bss input resb 5 ; 保留5字节空间存储输入 SECTION .text global _start _start: mov edx,5 mov ecx,input mov ebx,0 mov eax,3 int 80h ; 使用repe cmpsb比较5字节字符串 mov ecx,5 mov esi,input mov edi,porovnat repe cmpsb jz dal ; ecx为0时表示所有字节匹配成功 jnz konec dal: mov edx,5 mov ecx,zprava mov ebx,1 mov eax,4 int 80h jmp konec konec: mov ebx,0 mov eax,1 int 80h
内容的提问来源于stack exchange,提问作者IlikeAssemblyButIsuck-sorry
相关产品推荐
相关产品推荐

