从字符串中删除空格

时间:2011-11-18 19:29:45

标签: linux assembly x86 nasm

我正在尝试学习汇编(英特尔x86与Linux上的NASM)并且不出所料我遇到了一些麻烦。

以下是为了获取文本缓冲区,删除所有空格并将结果放在另一个缓冲区中。它是我正在做的一个更大的项目的一部分,作为一种学习方式,我首先单独开发每个部分。在实际项目中,消息将来自一个文件,这里我只是使用硬编码字符串(Msg)进行测试。

但它不起作用。我已经习惯了一段时间,但我确定我已经错过了某些基本概念或其他什么。

[SECTION .data]
Msg   db '    %d Whitespace, thanks      ', 10, 0

[SECTION .bss]
BUFFSIZE   equ 80 
BufferA    resb BUFFSIZE
BufferB    resb BUFFSIZE

[SECTION .text]
extern printf

global main

; PROCEDURE stripwhite
; INPUT     None
; OUTPUT    None
; NOTES     Strips all leading and trailing whitespace from BufferA
;           Result is stored in BufferB
stripwhite:
    pushad                  ; Save caller's registers

    mov eax, BufferA        ; Source string
    mov ebx, BufferB        ; Output string
    .loop:
        mov cl, byte [eax]  ; Get a single character from the source
        cmp cl, 0
        je .end             ; End if character is null
        cmp cl, 32
        jne .save           ; Save it if it's not a space
        add eax, 1          ; Otherwhise skip to next character
        jmp .loop
    .save:
        mov byte [ebx], cl  ; Save character in output buffer
        add eax, 1          ; Move on to next character
        add ebx, 1
        jmp .loop
    .end:
        mov byte [ebx], 0   ; Add a null at the end

    popad                   ; Restore caller's registers
    ret

main:
    push ebp                ; Set up stack frame for debugger
    mov ebp, esp
    push ebx                ; Must preserve ebp, ebx, esi and edi
    push esi
    push edi
    ; start

    mov dword [BufferA], Msg
    call stripwhite

    push 0
    push BufferB            ; Push message string
    call printf             ; Print line count
    add esp, 8              ; Clean up the stack

    ; end
    pop edi                 ; Restore saved registers
    pop esi
    pop ebx
    mov esp, ebp            ; Destroy stack frame
    pop ebp
    ret

我有点想知道为什么当dword和两个缓冲区都使用字节时,我必须在call stripwhite之前的行中使用Msg,但链接器(由在这种情况下,GCC)在我使用其他任何东西时抛出错误:

stripwhite.o:stripwhite.asm:82: relocation truncated to fit: R_386_8 against `.data'
collect2: ld returned 1 exit status

也许这与它有关,但我无法弄清楚是什么。

以下似乎工作正常,除了代码不在程序中之外,它基本相同。

[SECTION .data]
Msg   db '    %d Whitespace, thanks      ', 10, 0

[SECTION .bss]
BUFFSIZE   equ 80 
BufferA    resb BUFFSIZE
BufferB    resb BUFFSIZE

[SECTION .text]
extern printf

global main

main:
    push ebp                ; Set up stack frame for debugger
    mov ebp, esp
    push ebx                ; Must preserve ebp, ebx, esi and edi
    push esi
    push edi
    ; start

    mov eax, Msg
    mov ebx, BufferB
    .loop:
        mov cl, byte [eax]
        cmp cl, 0
        je .end
        cmp cl, 32
        jne .save
        add eax, 1
        jmp .loop
    .save:
        mov byte [ebx], cl
        add eax, 1
        add ebx, 1
        jmp .loop
    .end:
        mov byte [ebx], 0

    push 0
    push BufferB            ; Push message string
    call printf             ; Print line count
    add esp, 8              ; Clean up the stack

    ; end
    pop edi                 ; Restore saved registers
    pop esi
    pop ebx
    mov esp, ebp            ; Destroy stack frame
    pop ebp
    ret

1 个答案:

答案 0 :(得分:0)

[SECTION .bss]
BUFFSIZE   equ 80 
BufferA    resb BUFFSIZE
BufferB    resb BUFFSIZE

BufferA是一个数组。

mov dword [BufferA], Msg

这会将Msg的地址放在BufferA的前4个字节中,可能不是您想要的。您可以改为呼叫memcpy