Linux 为什么可以';是否使用int 0x80从指针写入堆栈内存?

Linux 为什么可以';是否使用int 0x80从指针写入堆栈内存?,linux,assembly,x86-64,system-calls,Linux,Assembly,X86 64,System Calls,上面的代码不会将任何内容打印到标准输出。当我给节.data中的一个字符一个ptr时,它就工作了。我做错了什么?30十进制是ASCII“记录分隔符”的代码。不管是什么,它可能不是一个可打印的字符 另一方面,30十六进制(NASM术语中的30h或0x30)是ASCII“0”的代码 此外,您还需要使用64位ABI。amd64使用与int 0x80不同的系统调用方法,尽管这可能仍然适用于安装的32位库等。而在x86上,可以执行以下操作: ; NASM push 30 ; '0' mov rax, 4

上面的代码不会将任何内容打印到标准输出。当我给
节.data
中的一个字符一个ptr时,它就工作了。我做错了什么?

30十进制是ASCII“记录分隔符”的代码。不管是什么,它可能不是一个可打印的字符

另一方面,30十六进制(NASM术语中的30h或0x30)是ASCII“0”的代码


此外,您还需要使用64位ABI。

amd64
使用与
int 0x80
不同的系统调用方法,尽管这可能仍然适用于安装的32位库等。而在
x86
上,可以执行以下操作:

; NASM
push 30 ; '0'

mov rax, 4 ; write
mov rbx, 1 ; stdout
mov rcx, rsp ; ptr to character on stack
mov rdx, 1 ; length of string = 1
int 80h
amd64
上,可以执行以下操作:

mov eax, SYSCALL_NUMBER
mov ebx, param1
mov ecx, param2
mov edx, param3
int 0x80
对于你想做的事情,考虑下面的例子:

mov rax, SYSCALL_NUMBER_64 ; different from the x86 equivalent, usually
mov rdi, param1
mov rsi, param2
mov rdx, param3
syscall

我确实忘记了h,你是对的,但在添加h后,它仍然不起作用。我甚至使用了gdb,rcx被设置为ptr,当我查询该ptr的值时,它是0x30。。。。我不知道在这种情况下有什么不对,我认为您可能混淆了32位ABI和64位ABI。请参阅。如果太长而无法读取,。在当今时代,使用带有int 80h的x86-64显然是错误的。您是否检查了
write
的返回值?它是否返回了
EFAULT
?@MichaelFoukarakis是的,它返回了-14.:(我认为他的代码使用
.data
中的地址的原因是
.data
从一个适合32b的地址开始,因此通过x86
int 0x80
ABI不会影响它。堆栈默认映射到一个高地址(其中高位都是1,而不是0)。
        bits 64
        global _start

section .text

_start:
        push            0x0a424242
        mov             rdx, 04h
        lea             rsi, [rsp]
        call            write
        call            exit
exit:
        mov             rax, 60     ; exit()
        xor             rdi, rdi    ; errno
        syscall

write:
        mov             rax, 1      ; write()
        mov             rdi, 1      ; stdout
        syscall
        ret