迭代汇编 x86 (asm) 中寄存器中存储的字符串

问题描述 投票:0回答:1

如果我有一个很长的字符串,其地址存储在 rdi 中,我是否可以迭代该字符串的每个字符?

这是我到目前为止尝试过的方法,但效率非常低,我仍然需要创建一个单独的方法来查找字符串的长度以终止循环。对于这个asm x86-64有更好的方法吗?到目前为止我只找到了这个),但是这里我的字符串仅存储在寄存器中并且无法在开始时定义。

假设在函数之前,指向字符串的指针已经移动到%rdi:


.global function

test:       .asciz "\nTest:`%c"

function:

pushq   %rbp
movq    %rsp, %rbp

pushq   %rdi
pushq   %rdi
movq    (%rdi)  %rax
movq    $0, %rbx
movq    $8, %rdx
pushq   %rax
pushq   %rbx

loop:
movzb   %al, %rcx
movq    %rcx, %rsi
movq    $test, %rdi
call    printf
movq    (%rsp), %rbx
movq    8(%rsp), %rax
movq    $8, %rdx
shr $8, %rax
incq    %rbx
cmpq    %rbx,%rdx
jne loop

next_byte:
add $8, %rdi
movq    (%rdi), %rax
movq    $0, %rbx
pushq   %rcx
pushq   %rdx
pushq   %rax
pushq   %rbx
jmp loop

movq    %rbp, %rsp
popq    %rbp
ret
assembly x86 x86-64 att
1个回答
0
投票

这是非常令人困惑的代码。为什么它有大量的推送?为什么一次加载 8 个字节而不是逐字节加载?为什么你要不必要地移动东西?你的字符串是否以零结尾?你可以这样做:

function:
    pushq %rbx
    mov %rdi, %rbx
loop:
    movzbl (%rbx), %esi
    test %esi, %esi
    jz done
    lea test(%rip), %rdi
    xor %eax, %eax
    call printf@plt
    inc %rbx
    jmp loop
done:
    popq    %rbx
    ret
© www.soinside.com 2019 - 2024. All rights reserved.