找不到错误!!尝试循环遍历字符串并将小写字母更改为x86汇编语言中的大写字母

时间:2018-03-05 19:21:54

标签: assembly x86 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

1 个答案:

答案 0 :(得分:6)

您想要多少错误?

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几乎肯定一见钟情等等......不要让你的大脑欺骗你,需要练习和技巧来克服这些。