编写汇编语言代码来反转字符串
Posted
技术标签:
【中文标题】编写汇编语言代码来反转字符串【英文标题】:Write an assembly language code to reverse a string 【发布时间】:2018-10-31 06:06:30 【问题描述】:这是一个反转字符串的代码 我真的很难完成这段代码。我找不到它有什么问题,但是输出是错误的。
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
【问题讨论】:
***.com/questions/33685870/… 你可以做mov edi, OFFSET target + SIZEOF target - 2
。或者只是在目标缓冲区的末尾放一个标签,然后执行mov edi, OFFSET end_target - 2
。无论如何,这段代码与您想要发生的事情有什么不同?它是否写入target
开头之前的 1 个字节或其他内容?
@NgSharma,这个问题有很多,--unhelpful-- 至少可以说是答案。
【参考方案1】:
将两个长度传递给函数有点奇怪。如果两者不匹配,可能会发生各种不好的事情。 最好明确地传递字符串的长度,或者让代码计算出长度。 由于获取 old-skool c-string 的长度对于代码来说并非易事,但对于谷歌来说却是微不足道的,我将把它作为参数传递。
'...输出错误。' 问题是您的字符串需要以零结尾,但您没有将终止零放在目标字符串上。
首先,如果您想让字符串成为有效的 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,那么你可以只在寄存器中传递参数,这意味着你可以跳过一些初始化。鉴于您的代码不会因原始速度而赢得任何奖励,因此我跳过了这一步。
【讨论】:
它不是函数,MASM 中的 SIZEOF 运算符是静态数据的汇编时事物。从之前的问题来看,我认为 OP 在已知长度的静态缓冲区中有以 0 结尾的 C 字符串,并且他们很难在终止符之前反转数据,然后只复制终止符。 @PeterCordes,是的,我已经有一段时间没有使用 MASM 了。我是正确的关于 0 终止是问题,感谢您确认。 length EQU SIZEOF source 这行 mov ecx, length 给了我一个语法错误 @Jinna:使用mov ecx, SIZEOF source
。或者在定义source
之后立即使用length = $ - source
。 ($
是当前位置,所以如果你把它放在其他任何地方,它会计算错误的大小。有关 NASM 版本,请参阅How does $ work in NASM, exactly?。我不确定 MASM 中的 EQU 是否正是你想要的,可能只是一个将在错误位置评估$
的文本替换;我认为=
肯定会在您编写它的位置被评估为一个数字(但仍然是一个不占用数据部分空间的汇编时间常数) .)以上是关于编写汇编语言代码来反转字符串的主要内容,如果未能解决你的问题,请参考以下文章
C语言试题二十六之请编写一个函数function(char *s),该函数的功反转字符串中的内容。