如何在 Assembly 中拆分/截断字符串变量值?

How to split / truncate a string variable value in Assembly?

我目前正在做一个项目,为了存储的缘故,我想在汇编中切断一个变量,并(可选)使它成为一个寄存器的值,例如 eax。

我需要使用 Intel 语法与 NASM 一起工作的代码。

例如,如果变量 "msg" 设置为“29ak49”,我想取其中的一部分,例如“9ak4”,并将其放入寄存器或类似的东西中。

正如评论中提到的Peter Cordes,您始终可以在现有字符串的缓冲区中添加一个空终止符(0)以进行右截断;如果您不介意修改原始字符串数据。

下面的示例将在不修改原始字符串的情况下检索子字符串。


如果你有一个变量的地址,并且知道要截断它的位置,你可以取数据起始位置的地址,并在左截断处添加一个偏移量。要右截断,您可以从新偏移量中读取任意数量的字符。

例如 x86:

    msg db '29ak49'         ; create a string (1 byte per char)


    ;; left truncate
    mov esi, msg            ; get the address of the start of the string
    add esi, OFFSET_INTO_DATA ; offset into the string (1 byte per char)

    ;; right truncate
    mov edi, NUM_CHARS      ; number of characters to take

    .loop:                  
    movzx eax, byte [esi]   ; get the value of the next character
    ;; do something with the character in eax   
    inc esi
    dec edi
    jnz .loop

    ;; end loop

编辑:

以下是作为 32 位 Linux 应用程序的可运行测试实现,它打印出根据 OFFSET_INTO_DATANUM_CHARS 选择的子字符串(note:算法是一样的,只是寄存器变了):

        section .text
        global _start


_start:

        ;; left truncate
        mov esi, msg            ; get the address of the start of the string
        add esi, OFFSET_INTO_DATA ; offset into the string (1 byte per char)

        ;; right truncate
        mov edi, NUM_CHARS      ; number of characters to take

        .loop:                  
        mov ecx, esi            ; get the address of the next character
        call print_char_32        
        inc esi
        dec edi
        jnz .loop

        jmp halt


;;; input:      ecx      -> character to display
print_char_32:
        mov edx, 1              ; PRINT
        mov ebx, 1              ;
        mov eax, 4              ;
        int 0x80                ;
        ret


halt:
        mov eax, 1              ; EXIT
        int 0x80                ;
        jmp halt


section .data

       msg db '29ak49'         ; create a string (1 byte per char)


       OFFSET_INTO_DATA EQU 1
       NUM_CHARS EQU 3

编译:

nasm -f elf substring.asm ; ld -m elf_i386 -s -o substring substring.o