【发布时间】:2021-07-22 15:16:26
【问题描述】:
我正在学习 nasm。我编写了一个简单的函数,将内存从源复制到目标。我在 C 中测试。
section .text
global _myMemcpy
_myMemcpy:
mov eax, [esp + 4]
mov ecx, [esp + 8]
add [esp + 12], eax
lp:
mov dl, [ecx]
mov [eax], dl
inc eax
inc ecx
cmp eax, [esp + 12]
jl lp
endlp:
mov eax, [esp + 4]
ret
还有 C 程序:
#include <string.h>
#define Times 340000000
extern void* _myMemcpy(void* dest, void* src, size_t size);
char sr[Times];
char ds[Times];
int main(void)
{
memset(sr, 'a', Times);
_myMemcpy(ds, sr, Times);
return 0;
}
我目前使用的是 Ubuntu 操作系统。当我用$ nasm -f elf m.asm && gcc -Wall -m32 m.o p.c && ./a.out 编译和链接这两个文件时,当Times 的值小于340000000 时,它可以正常工作。当它更大时,_myMemcpy 仅将源的第一个字节复制到目标。我无法弄清楚问题出在哪里。每个建议都会很有用。
【问题讨论】:
-
您正在对指针进行有符号比较;对于像
size = 0x1443fd00这样的巨大数组,其中一个将跨越 2GiB 边界(有符号环绕),除非链接器特别注意将一个放在高半部分,另一个放在低半部分。但它不会,它会使 .bss 连续。 -
所以将
jl替换为jb。让我们知道它是否有效! -
eax 是 32 位寄存器,Times 是 64 位
-
@PeterCordes,谢谢!它适用于
jb。 -
@PaulHankin:这是 32 位代码;当使用 32 位指针作为地址时,您可以通过堆栈参数和不分段错误来判断。 Times 是一个宏:
340000000是0x1443fd00。作为 C 字面量,它适合 32 位int,因此它在任何 C 实现中都具有类型int,且 int 至少为 32 位。
标签: c pointers assembly x86 nasm