在linux中,您可以使用系统调用号码4打印内容:
mov eax,4 ;system call number
mov ebx,0 ;file descriptor
mov ecx,msg ;adress of message in data segment
mov edx,length ;length of message
但是,你如何从堆栈段打印东西?
我试过了:
push 'H'
push 'e'
push 'l'
push 'l'
push 'o'
push ' '
push 'w'
push 'o'
push 'r'
push 'l'
push 'd'
mov eax,4 ;system call number
mov ebx,0 ;file descriptor
mov ecx,ebp ;adress of message
mov edx,11 ;length of message
但是没有打印任何东西。
编辑:我对代码进行了一些更改,现在就是这样:
section .data
msg: db "Hola mundo",0Ah
ok: db "OK",0Ah
section .text
global _start
_start:
push 'leH'
push 'w ol'
push 'dlro'
mov eax,4 ;system call number
mov ebx,1 ;file descriptor
mov ecx,esp ;adress of message in data segment
mov edx,11 ;length of message
mov eax,1
xor ebx,ebx ;same as move ebx,0 but better
int 0x80
编辑2 (仍然无效)
section .data
msg: db "Hello world",0Ah
section .text
global _start
_start:
push 'leH'
push 'w ol'
push 'dlro'
mov eax,4 ;system call number
mov ebx,1 ;file descriptor
mov ecx,esp ;adress of message in data segment
mov edx,11 ;length of message
int 0x80
mov eax,1
xor ebx,ebx ;same as move ebx,0 but better
int 0x80
回应评论,我汇编并编译:
nasm -f elf64 hello.asm && ld hello.o && ./a.out
我在Ubuntu 64位Linux中工作。
答案 0 :(得分:2)
这个问题最初缺乏关键信息。您组装并链接:
nasm -f elf64 hello.asm && ld hello.o && ./a.out
这会生成64位可执行文件。 int 0x80
不应该用于64位可执行文件。在64位程序中,堆栈指针不能仅在32位 ESP 寄存器中表示。使用64位指针的唯一方法是使用syscall
指令。 Ryan Chapman's blog通过syscall
指令提供了有关使用64位系统调用接口的详细信息。
如果您修改代码以符合该界面,它可能类似于:
section .text
global _start
_start:
mov dword [rsp-4], `rld\n`
; Use back ticks instead of single quotes
; To parse the string like C. We can write safely
; in the 128 bytes below RSP because of the
; Linux red zone.
mov dword [rsp-8], 'o Wo'
mov dword [rsp-12],'Hell'
mov eax,1 ;Write system call number
mov edi,eax ;file descriptor (1 = stdout)
lea rsi,[rsp-12];address of message on the stack
mov edx,12 ;length of message
syscall
mov eax,60 ;Exit system call
xor edi,edi ;RDI=0
syscall
此代码将常量写入32位寄存器,因为它们零扩展到整个64位寄存器。我们无法推送64位立即数,但我们可以将字符串直接写为32位DWORD值。我们不需要调整 RSP ,因为Linux有一个128字节red zone,可以防止被异步事件和信号破坏。
如果您想使用带有 C 转义字符的 C 样式字符串, NASM supports backtick而不是单引号做出区分。这允许您使用\n
之类的字符作为表示新行字符的字符。我提到这一点,因为您似乎想在您的问题中发布的一些代码中放置换行符,该代码已被删除。