coc*_*d'3 -4 x86 assembly nasm
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
Run Code Online (Sandbox Code Playgroud)
你想要多少错误?
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
Run Code Online (Sandbox Code Playgroud)
这将加载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
Run Code Online (Sandbox Code Playgroud)
第一个字母不是零值,所以jne会跳转到end:.你也没有定义零字节msg,所以一旦你将条件翻转到je,你就有可能在定义之后处理更多的字节msg,直到在内存中偶然发现一些随机零(实际上会有一个权利)后msg作为填充,这样你就不会注意到这个错误,除非你有理由对你的代码正确).
cmp byte [ESI+ECX], 0x61 ; compare with lower bound of lowercase
jl startloop
Run Code Online (Sandbox Code Playgroud)
在处理ASCII值时,我倾向于以无符号方式考虑它们,即jb不是jl.而且,0x61您可以使用NASM 'a',它的IMO更具可读性.
cmp byte [ESI+ECX], 0x7A
jg startloop
Run Code Online (Sandbox Code Playgroud)
我再次宁愿使用无符号跳转ja和'z'常量.
add byte [ESI+ECX], eax
Run Code Online (Sandbox Code Playgroud)
这甚至eax是如何编译的... 是32位,而不是8位,所以byte关键字可能被忽略了.如果你打开所有警告,NASM可能会发出一些(懒得试试自己).您也加入32到小写字母,所以从0x61对'a'你会去值0x81,这在Linux中,当解释为ASCII 7b的不可显示字符(虽然UTF-8编码或其他一些你可能会得到一些输出).
end:
ret
Run Code Online (Sandbox Code Playgroud)
在破坏单个小写字母之后,你就会掉头了end:.
足够?并且使用调试器,通过读取源来发现汇编错误需要多年的经验,即使只是读取调试器屏幕通常需要高度关注,实际上注意到与原始期望的微妙差异,如0x91而不是0x61几乎肯定一见钟情等等......不要让你的大脑欺骗你,需要练习和技巧来克服这些.