x86汇编语言中的存储和字符串操作



我刚刚学习汇编语言编码。

问:将表示任何有符号整数的字符串转换为其 2 的补码值,结果以小端顺序存储在内存的连续位置。

例如 - 1 = 0xFFFFFFFFFFFFFFFE假设 2 的补码代码是 64 位的。我已经在我的代码中完成了数字 -149,这应该会导致 0xffff ffff ffff ff6b

.data
S:  .string "-149"
Result:     .quad
.text
.globl main
main: 
mov     S,%rax
cmp     %rax,0
jl      positive
sub     %rax,%rax
not     S
add     S,%rax
sub     $30,%rax
not     %rax
add     $1, %rax
mov     %rax,Result
positive:
sub     $30,%rax
not     %rax
add     $1,%rax 
mov     %rax,Result

在 GDB 中,存储的字符串整数的值为 this。

(gdb) x/24xb &S
0x601038:   0x2d    0x31    0x34    0x39    0x00    0x00    0x00    0x00
0x601040:   0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00
0x601048:   0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00

如果我想对 -149 进行任何计算,我必须以某种方式访问内存中的这些位置 - 我该如何做到这一点?

如果我知道 4 在 10 的位置,我可以将其乘以 10 得到 40,然后将 9 和类似的 1x100 相加得到 100 并添加它。

如何访问它们进行计算?

如何访问它们进行计算?

字符串作为连续字符存储在内存中。 如果是 ASCII(不是 UTF-8),则每个字符都是一个字节。

因此,您可以使用字节加载/存储一次访问一个,例如movzbl 2(%rsi), %eax获取第 3 个字符(如果rsi指向字符串的开头)。

或者,如果%rdi指向最后一个字符(十进制数中的字符),则imul $10, -1(%rdi), %ecx%cl设置为倒数第二个字符加上其位值。 (和%ecx的上字节到垃圾;最好先做一个movzx加载,然后再做一个乘法。 不过,这确实可以使低 8 位正确)。

在复杂性范围的另一端,请查看此SSE4.1 IPv4点分四字符串到32位整数转换器。 具体来说,随机播放之后的小数位值部分,使用pmaddubsw(_mm_maddubs_epi16)和向量[ ..., 100, 10, 1 ]来应用位值和一步的水平加法,然后phaddw水平添加每个虚线四边形中最多三位数字。

还有如何使用 SIMD 实现 atoi?

另请参阅 x86 标签 wiki 以获取许多其他链接。

好吧,我希望这甚至不会编译(例如cmp %rax,0AT&T语法中不是有效的组合,这看起来像你想要英特尔语法)。

还有一些事情没有任何意义,比如not S......你认为这会有什么作用?如果你把它注释为字节ptr,它会反转"<"字符(实际上为什么你在S字符串中有"<"和">"也让我感到困惑)。

等等等等...

所以先尝试编译它,然后在调试器中打开它,逐条指令一步一步地步进,并继续查看 CPU 寄存器和内存和指令参考指南......直到它有意义...可能需要一些时间,但实际上不会那么长,也许几天,你会掌握它。

最新更新