找不到错误!!尝试循环遍历字符串并使用x86汇编语言将小写字母更改为大写字母
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了找不到错误!!尝试循环遍历字符串并使用x86汇编语言将小写字母更改为大写字母相关的知识,希望对你有一定的参考价值。
section .data
msg db "sum of x and y is " ;String
section .text
global _start
_start:
Change_letter:
mov ECX, -1 ;set counter
mov ESI, [msg] ; move string address to ESI
mov Eax , 32 ; mov 32 to eax for change lowercase to uppercase
startloop:
inc ecx ;
cmp byte [ESI+ecx], 0x00 ;compare with null
jne end
cmp byte [ESI+ECX], 0x61 ; compare with lower bound of lowercase
jl startloop
cmp byte [ESI+ECX], 0x7A
jg startloop
add byte [ESI+ECX], eax
end:
ret
答案
你想要多少错误?
section .data
msg db "sum of x and y is " ;String
section .text
global _start
_start:
Change_letter:
mov ECX, -1 ;set counter
mov ESI, [msg] ; move string address to ESI
这会将esi
加载到字符串的前4个字符,而不是地址。
mov Eax , 32 ; mov 32 to eax for change lowercase to uppercase
startloop:
inc ecx ;
cmp byte [ESI+ecx], 0x00 ;compare with null
jne end
第一个字母不同于零值,所以jne
将跳转到end:
。你也没有在msg
中定义零字节,所以一旦你将条件转换为je
,你就有可能在定义的msg
之后处理更多的字节,直到在内存中偶然发现一些随机零(实际上会有在msg
之后是一个填充,所以你不会注意到这个错误,除非你正确地推理你的代码)。
cmp byte [ESI+ECX], 0x61 ; compare with lower bound of lowercase
jl startloop
在处理ASCII值时,我倾向于以无符号方式考虑它们,即jb
,而不是jl
。也可以使用NASM 0x61
代替'a'
,它的IMO更具可读性。
cmp byte [ESI+ECX], 0x7A
jg startloop
我再次宁愿使用无符号跳跃ja
和'z'
常数。
add byte [ESI+ECX], eax
这甚至如何编译... eax
是32位,而不是8位,所以byte
关键字可能被忽略。如果你打开所有警告,NASM可能会发出一些(懒得试试自己)。你也在将32
添加到小写字母中,所以从0x61
为'a'
你会去重视0x81
,在linux中它是不可打印的字符,当被解释为7b ASCII时(虽然使用UTF-8编码或其他一些你可能得到一些输出)。
end:
ret
在损坏单个小写字母后,你会掉到end:
。
足够?并且使用调试器,通过读取源来发现汇编错误需要多年的经验,即使只是读取调试器屏幕通常需要高度关注,实际上注意到与原始期望的微妙差异,如0x91而不是0x61几乎肯定一见钟情等等......不要让你的大脑欺骗你,需要练习和技巧来克服这些。
以上是关于找不到错误!!尝试循环遍历字符串并使用x86汇编语言将小写字母更改为大写字母的主要内容,如果未能解决你的问题,请参考以下文章