【发布时间】:2011-11-18 19:29:45
【问题描述】:
我正在尝试学习汇编(Linux 上带有 NASM 的 Intel x86),不出所料,我遇到了一些麻烦。
以下内容旨在获取文本缓冲区,删除所有空格并将结果放入另一个缓冲区。这是我正在做的一个更大项目的一部分,作为一种学习方式,我首先单独开发每个部分。在实际项目中,消息将来自文件,这里我只是使用硬编码字符串 (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
我有点想知道为什么当Msg 和两个缓冲区都使用字节时,我似乎必须在上面的call stripwhite 之前的行中使用dword,但是链接器(在这种情况下由 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
【问题讨论】: