如何在x86中实现内存寻址负偏移以避免小端序字符串反转?
解决x86内存寻址负偏移实现数字转字符串的问题
嘿,我来帮你搞定这个x86下的内存寻址问题!首先得明确:你想通过反向存储ASCII字符来避免小端序导致的字符串反转,这个思路是对的,但x86的基址+变址寻址模式里,比例因子只能是1、2、4、8这几个正数,所以你原来写的movb %al, -8(%rbp, %r12, -1)确实是非法的,这也是你卡住的核心原因。
正确的实现思路
我们的目标是:把数字拆解出的ASCII字符(从低位到高位)反向存入栈空间,让最终内存里的字符串是高位到低位的顺序(符合正常字符串的存储逻辑)。具体可以用两种方式实现:
方式1:用寄存器计算动态偏移(和你的尝试思路一致,优化细节)
假设%r12是当前处理的字符索引(从0开始,对应数字的低位到高位),我们需要把每个字符存在rbp - 8 - r12的位置,步骤如下:
; 初始化偏移寄存器%r13为-8(对应第一个低位字符的存储位置) mov $-8, %r13 ; 减去当前索引%r12,得到目标偏移:-8 - r12 sub %r12, %r13 ; 将ASCII字符(存在%dl中)存入目标地址 movb %dl, (%rbp, %r13)
每次处理下一个字符时,只需要让%r12自增,重复上述计算即可。
方式2:用寄存器跟踪存储位置(更高效)
如果是循环处理所有字符,我们可以直接用一个寄存器跟踪当前要存储的地址,每次循环后让地址减1,省去重复计算偏移的步骤:
; 假设数字的总位数存在%r14中 mov $-8, %r13 ; 初始指向字符串的末尾位置(第一个低位字符存在这里) mov $0, %r12 ; 循环计数器初始为0 digit_to_str_loop: ; --- 这里先写数字转ASCII的逻辑,结果存入%dl --- ; 比如:取数字模10,加48得到ASCII码 ; 将当前ASCII字符存入目标栈地址 movb %dl, (%rbp, %r13) dec %r13 ; 下一个字符往更低的地址存(对应数字的更高位) inc %r12 cmp %r12, %r14 ; 判断是否处理完所有位数 jne digit_to_str_loop
循环结束后,字符串的起始地址就是%rbp + %r13 + 1(因为最后一次dec后,%r13指向了起始地址的前一个字节),直接从这个地址开始输出就是正确顺序的数字字符串。
为什么这样能避免小端序问题?
数字在x86的寄存器/内存中是小端存储(低位字节在低地址),但我们转字符串时是从数字的低位开始取字符,然后把这些字符从高地址往低地址依次存储,最终内存里的字符串就是:低地址存数字的高位字符,高地址存低位字符,完全符合正常字符串的存储顺序,输出时自然不会反转。
内容的提问来源于stack exchange,提问作者samuelbrody1249
相关产品推荐
相关产品推荐

