在堆栈中打印一些东西(组装) [英] Printing something in stack (assembly)

查看:61
本文介绍了在堆栈中打印一些东西(组装)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Linux 中,您可以使用系统调用号 4 打印一些内容:

In linux you can print something using the system call number 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

但是,你如何从堆栈段打印一些东西?

But, How do you print something from stack segment?

我试过了:

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

但不打印任何内容.

我对代码进行了一些更改,现在是这样:

I made some changes to my code and now it is so:

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

EDIT 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

响应评论,我汇编和编译:

Responding to the comment, I assemble and compile with:

nasm -f elf64 hello.asm && ld hello.o && ./a.out

我在 Ubuntu 64 位 Linux 中工作.

I'm working in Ubuntu 64-bit Linux.

推荐答案

这个问题最初缺少一个关键信息.您组装和链接:

The question was originally lacking a key piece of information. You assemble and link with:

nasm -f elf64 hello.asm && ld hello.o && ./a.out

这会生成一个 64 位可执行文件.int 0x80 不应在 64 位可执行文件中使用.在 64 位程序中,堆栈指针不能仅在 32 位 ESP 寄存器中表示.使用 64 位指针的唯一方法是使用 syscall 指令.Ryan Chapman 的博客 提供了有关通过 syscall 指令.

This generates a 64-bit executable. int 0x80 shouldn't be used in 64-bit executables. In 64-bit programs that stack pointer can't be represented in just the 32-bit ESP register. The only way to use 64-bit pointers is to use the syscall instruction. Ryan Chapman's blog has good information on using the 64-bit system call interface via the syscall instruction.

如果您修改代码以符合该接口,它可能如下所示:

If you modify your code to conform to that interface it could look something like:

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 字节的 防止被异步事件和信号破坏的红色区域.

This code writes constants to 32-bit registers as they are zero extended to the entire 64-bit register. We can't push 64-bit immediate values, but we can write the string onto the stack directly as 32-bit DWORD values. We don't need to adjust RSP because Linux has a 128 byte red zone that is protected from being clobbered by asynchronous events and signals.

如果您想使用带有 C 转义字符的 C 样式字符串,NASM 支持反引号而不是单引号来区分.这允许您使用诸如 \n 之类的东西作为表示换行符的字符.我提到这一点是因为您似乎想在您的问题中发布的一些代码中放置一个换行符,这些代码已被删除.

If you want to use C style strings with C escape characters in it, NASM supports backtick instead of single quote to make the distinction. This allows you to use something like \n as a character denoting the new line character. I mention this as it seems you wanted to place a newline character in some of the code that was posted in your question that has since been removed.

这篇关于在堆栈中打印一些东西(组装)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆