函数适用于堆栈上的缓冲区,但不适用于 .data 或 .bss 部分? [英] Function works with buffers on the stack but not in .data or .bss sections?

查看:60
本文介绍了函数适用于堆栈上的缓冲区,但不适用于 .data 或 .bss 部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

global _start
extern GetStdHandle, WriteConsoleA ;kernel32.dll

section .data:
    buf times 12 db 0

section .text:
_uint32_to_string:
;void uint32_to_string(uint32_t n, char* buffer)
;buffer: 11 bytes (minimum)
    push ebp
    push ebx
    push esi
    push edi
    mov ebp, esp
    mov ebx, [ebp + 24]
    xor edi, edi
    mov eax, [ebp + 20]
    mov ecx, 10
CREATE_UINTEGER_STRING:
    xor edx, edx
    div ecx
    add dl, '0'
    mov [ebx + edi], dl
    inc edi
    cmp eax, 0
    jne CREATE_UINTEGER_STRING
    xor esi, esi
REVERSE_STRING_UNSIGNED:
    mov ecx, 2
    mov eax, edi
    xor edx, edx
    div ecx
    cmp esi, eax
    jnl REVERSE_UNSIGNED_STRING_END
    mov eax, ebx
    add eax, edi
    sub eax, esi
    dec eax
    mov cl, [ebx + esi]
    mov dl, [eax]
    mov [ebx + esi], dl
    mov [eax], cl
    inc esi
    jmp REVERSE_STRING_UNSIGNED
REVERSE_UNSIGNED_STRING_END:
    mov byte [ebx + edi], 0
    mov esp, ebp
    pop edi
    pop esi
    pop ebx
    pop ebp
    ret

_string_length:
;uint32_t string_length(const char* s)
    push ebp
    mov ebp, esp
    mov ecx, [ebp + 8]
    xor eax, eax
GET_STRLEN:
    cmp byte [ecx + eax], 0
    je END_GET_STRLEN
    inc eax
    jmp GET_STRLEN
END_GET_STRLEN:
    mov esp, ebp
    pop ebp
    ret

_start:
    mov ebp, esp
    mov eax, 235 ;here is the number to be printed
    lea ebx, [buf] ;it works if instead of this line I write:
    ; sub esp, 12
    ; mov ebx, esp
    push ebx
    push eax
    call _uint32_to_string
    add esp, 8
    push ebx
    call _string_length
    add esp, 4
    mov edi, eax
    push dword -11
    call GetStdHandle
    push dword 0
    push dword 0
    push edi
    push ebx
    push eax
    call WriteConsoleA
    mov esp, ebp
    xor eax, eax
    ret

我正在使用这个程序在控制台屏幕上打印一个数字.问题是,如果出于某种原因,我选择将 .data 中分配的缓冲区传递给 _uint32_to_string 函数,则程序会出现运行时错误并以乱码退出代码退出.如果我尝试在 .bss 部分中定义缓冲区,如下所示,NASM 会给我一个警告(如果我运行它,程序仍然以垃圾状态退出):

I am using this program to print a number on the console screen. The problem is that if, for some reason, I choose to pass a buffer allocated in .data to the _uint32_to_string function, the program gives me a runtime error and exits with a gibberish exit code. If I try to define the buffer in the .bss section like the following, NASM gives me a warning (and the program still exits with garbage status if I run it):

section .bss:
    buf resb 12
;error: print_program.asm:5: warning: uninitialised space declared in non-BSS section `.bss:': zeroing

幸运的是,如果我在堆栈上分配缓冲区,程序可以正常工作,打印数字并以状态零退出.

Luckily, if I allocate the buffer on the stack the program works correctly, prints the number and exits with status zero.

谁能帮我理解为什么程序可以使用分配在堆栈上的缓冲区而不是 .data.bss 的缓冲区?

Can anybody please help me understand why the program works with buffers allocated on the stack but not with .data or .bss ones?

P.S:如果重要,这里是我编译代码的方式(平台:Windows 10 32 位):

P.S: If it matters, here is how I compile my code (platform: Windows 10 32-bit):

nasm -f win32 -o print_program.obj print_program.asm
golink print_program.obj /console /entry _start kernel32.dll

推荐答案

所以,感谢@fuz,sections 之后不应该有任何冒号.这意味着 section .data: 应该是 section .data..bss.text 相同.

So, thanks to @fuz, there shouldn't be any colons after the sections. That means section .data: should be section .data. Same for .bss and .text.

这篇关于函数适用于堆栈上的缓冲区,但不适用于 .data 或 .bss 部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆