如何在 x86-64 汇编中使用堆栈?

Posted

技术标签:

【中文标题】如何在 x86-64 汇编中使用堆栈?【英文标题】:How to use the stack in x86-64 Assembly? 【发布时间】:2014-12-02 01:01:03 【问题描述】:

我在如何访问堆栈中的变量时遇到了一些麻烦。这是我正在做的事情:

.data
.text
input:
    .string "%ld"   #format for input
output:
    .string "%ld.\n"    #format for output

.global main
pushq   %rbp                    #push base pointer, also known as frame pointer
movq    %rsp, %rbp              #set base pointer to stack pointer, reference off of rbp for locals

subq    $8, %rsp                #allocate 16 bytes for local use
movq    $input, %rdi            #calls scanf in the format of input
movq    %rsp, %rsi
movq    $0, %rax
call    scanf


subq    $8, %rsp
movq    $input, %rdi            #calls scanf in the format of input
movq    %rsp, %rsi
movq    $0, %rax
call    scanf

movq    -8(%rsp), %rbx          #stores first number into reg rbx
movq    (%rbx),%rbx
movq    -16(%rsp), %rcx         #stores second number into reg rcx
movq    (%rcx),%rcx


movq    $output,%rdi            #prints in format input
movq    $0, %rax
movq    %rcx, %rsi
call    printf

addq $16, %rsp
popq %rbp
ret

我用scanf 读入两个整数,然后尝试将它们存储到rbxrcx 寄存器中。但是,当我尝试打印其中一个时,它只会打印出一些随机整数。

【问题讨论】:

一级太多间接性:movq (%rbx), %rbx,movq (%rcx), %rcx 需要离开。 @EOF 它仍然打印出一个随机整数。 哦,对了。你从错误的地方加载。 movq -8($rsp), %rbx 应该是 movq (%rsp), %rbxmovq -16(%rsp), %rcx 应该是 movq 8(%rsp), %rcx 【参考方案1】:

如果您在rsp 上执行自己的操作,那么显然第二个数字仍位于地址(%rsp),因为没有任何变化,而第一个数字位于8(%rsp),因为您从@987654324 中减去了8 @因为你已经读过了。另外,正如@EOF 所说,您不需要间接:

movq    8(%rsp), %rbx        #stores first number into reg rbx
movq    (%rsp), %rcx         #stores second number into reg rcx

请注意,调用约定要求保留rbx,因此破坏它是个坏主意。 x86-64 有很多其他寄存器可供选择;)(但请注意,其他一些寄存器也需要保留)。

【讨论】:

谢谢!那成功了!我会改用 r10 和 r11 :)

以上是关于如何在 x86-64 汇编中使用堆栈?的主要内容,如果未能解决你的问题,请参考以下文章

在 linux 上根据 x86-64 调用约定设置本地堆栈

堆栈、数据和指令段在哪里实现?

在汇编 x86-64 中划分 longfloat 和 int

x86_64 ABI:反汇编问题

x86-64 汇编中的数组元素比较(AT&T 语法)

如何在64位的Linux系统上使用汇编和C语言混