我正在尝试学习汇编(英特尔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
答案 0 :(得分:0)
[SECTION .bss]
BUFFSIZE equ 80
BufferA resb BUFFSIZE
BufferB resb BUFFSIZE
BufferA
是一个数组。
mov dword [BufferA], Msg
这会将Msg
的地址放在BufferA
的前4个字节中,可能不是您想要的。您可以改为呼叫memcpy
。