gpt4 book ai didi

assembly - 在 x86 汇编中实现 memset

转载 作者:行者123 更新时间:2023-12-02 21:47:13 24 4
gpt4 key购买 nike

我正在尝试在程序集 x86 中实现 memset。两者都按字节和按字进行复制,因此我会得到两个函数:kmemsetkmemsetw,我以这种方式向我的 C 代码公开:

extern uint8_t* kmemset(uint8_t* dest, uint8_t val, uint8_t size);  
extern uint16_t* kmemsetw(uint16_t* dest, uint16_t val, uint8_t size);

问题是当我测试它时,我遇到了段错误。我尝试使用 gdb 进行调试,但似乎无法单步执行 asm 代码。如果有人可以对代码发表评论,我会很高兴。 (kmemset 非常相似,所以我没有包含它)。

.intel_syntax noprefix  
.section .text
.align 16
.global kmemsetw
.type kmemsetw, @function

kmemsetw:
push ebp
mov ebp, esp
push edi
push ecx
push ebx
xor eax, eax
mov ebx, [ebp+4]
mov ax, [ebp+8]
mov ecx, [ebp+12]
mov edi, ebx
rep stosw
mov eax, edi
pop ebx
pop ecx
pop edi
pop ebp
ret

最佳答案

您在程序中没有使用ebx,为什么要保存它?它不需要保存。 ecx是一个 volatile 寄存器,您不需要保存它。

正如 gnometorule 所提到的,您的过程中的参数已关闭。

另一个大问题是你不会在最后恢复堆栈指针。当然你pop ebp,但是你在哪里mov esp, ebp???您可以在开头mov ebp, esp,但永远不要反转它。

如果你查看memset,它会返回传递给过程的指针。所以,这是错误的:mov eax, edi 应该是:mov eax, [ebp + 8]rep stos? 增加 edi 中的指针,因此如果返回 edi,则返回的指针是错误的。

但是为什么要为这个小过程设置一个堆栈框架呢?只需使用esp,因为我们需要将edi保存到堆栈中,esp中的参数将被偏移,就像我们设置一个堆栈帧:

kmemset:      
push edi ; proc uses edi, so save it.

mov ecx, [esp + 16] ; size_t num
mov al, [esp + 12] ; int value
mov edi, [esp + 8] ; void * ptr
rep stosb

mov eax, [esp + 8] ; return pointer
pop edi ; restore edi
ret ; let caller adjust stack

使用 stosw 会有点不同。

SomeProc:
push ebp
mov ebp, esp
push edi

; params are at:
;~ ebp + 8
;~ ebp + 12
;~ ebp + 16
etc...
; ...
; ...
; ...

pop edi
; the following 2 lines
; can be replaced with
; leave
mov esp, ebp
pop ebp
ret

关于assembly - 在 x86 汇编中实现 memset,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20331000/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com