为何64位SYSCALL接口可成功创建文件,32位int $0x80调用却失败?
syscall Works But int $0x80 Doesn't for Creating Files Great question—this boils down to a critical difference in Linux system call ABIs (Application Binary Interfaces) between 32-bit and 64-bit architectures. Let's break down exactly why your int $0x80 approach failed, and why syscall fixed it:
Mismatched System Call Numbers
Linux maintains completely separate sets of system call numbers for 32-bit and 64-bit environments. For example, theopensyscall (used to create files) has a call number of5in 32-bit (__NR_open), but2in 64-bit. If you're writing a 64-bit program and usingint $0x80(the 32-bit entry point), passing a 64-bit call number will make the kernel misinterpret your request—so it won't execute the file creation logic you intended.Different Register Passing Rules
The two syscall mechanisms use entirely different registers to pass arguments:- For
int $0x80(32-bit), arguments go intoebx,ecx,edx,esi,edi,ebp(in order). - For
syscall(64-bit), arguments userdi,rsi,rdx,r10,r8,r9.
If you wrote your 64-bit code to pass the filename pointer (argv[1]) intordi(as you should for 64-bit), then usedint $0x80, the kernel would look for the filename inebxinstead. That register would hold garbage or an invalid pointer, so the kernel couldn't find your desired filename to create the file.
- For
64-bit Address Truncation
64-bit programs use 8-byte pointers that can reference the full 64-bit address space. When you useint $0x80, the kernel treats all registers as 32-bit values, so it truncates your 64-bit filename pointer to its lower 32 bits. If your pointer happens to have a non-zero upper 32 bits (common in modern 64-bit systems), this truncated address will be invalid—meaning the kernel can't access the string containing your filename.ABI Compatibility Limits
int $0x80is designed for 32-bit programs running on 32-bit or 64-bit kernels (via compatibility layers). 64-bit programs can technically use it, but only if they strictly adhere to 32-bit calling conventions (including using 32-bit pointers and call numbers). This is almost never what you want in a native 64-bit program, hence the failure when you tried to use it with your argv[1] pointer.
To Sum It Up
When you switched to syscall, you started using the native 64-bit system call interface that matches your program's architecture. This meant your call number, argument registers, and pointer values were all interpreted correctly by the kernel—so it could finally create the file with the name you passed via argv[1].
内容的提问来源于stack exchange,提问作者AAJ

