[英]Write an assembly language code to reverse a string
这是一个反转字符串的代码我真的很难完成这段代码。 我找不到它有什么问题,但是输出是错误的。
mov esi, OFFSET source
mov edi, OFFSET target
add edi, SIZEOF target-2
mov ecx, SIZEOF source-1
L1:
mov al, [esi]
mov [edi], al
inc esi
dec edi
loop L1
向函数传递两个长度有点奇怪。 如果两者不匹配,可能会发生各种不好的事情。 最好明确传递字符串的长度,或者让代码计算出长度。
由于获取 old-skool c-string 的长度对代码来说很重要,但对 google 来说很简单,我将把它作为参数传递。
“……输出错误。”
问题是您的字符串需要以零结尾,但您没有将终止零放在目标字符串上。
首先,如果您想让字符串成为有效的 c 样式字符串,请确保添加终止零,如下所示: source db "test test",0
mov esi, OFFSET source ;Start of source
mov edi, OFFSET target ;start of dest
;length EQU SIZEOF source ;we are reversing source
mov ecx, SIZEOF source ;Length of the string
;(includes the terminating 0)
Setup:
;//a c-string must have a terminating 0!
xor eax,eax ;al=0, put the terminating zero in first
L1:
mov [edi+ecx-1], al ;if length(ecx)=1, then write to [edi] directly.
mov al, [esi]
inc esi
loop L1
代码备注
不需要保持三个计数器在飞行中( edi
, esi
, ecx
),两个就足够了。 esi
倒计时, ecx
倒计时。
x86 有很多非常有用的寻址模式,它们大多是免费的性能明智的。
最后一次迭代将读取al
的终止零,我们不需要反转它,并且您已经在开始时编写了它,所以它被(悄悄地)删除了。
由于终止为零,长度至少为 1。这很好,因为如果以某种方式将 0 送入loop
,它将“永远”循环; 不好(“永远”是 4+ 十亿次) 。
请注意,您的代码没有考虑 Unicode,因此它不适用于 UTF8,但我们假设它只是一个学习练习。
如果你遵循ABI ,那么你可以只在寄存器中传递参数,这意味着你可以跳过一些初始化。 鉴于您的代码不会因原始速度而获得任何奖励,因此我跳过了这一步。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.