这个 x86 汇编代码如何创建一个字符串?
How does this x86 Assembly code create a string?
我正在学习x86汇编语言。为了更好地理解字符串创建幕后发生的事情,我有一个示例程序,它只打印一个字符串。 GCC 生成了以下汇编程序,我无法理解编译器的输出:
汇编代码:
Dump of assembler code for function main:
0x0000000000400596 <+0>: push %rbp
0x0000000000400597 <+1>: mov %rsp,%rbp
0x000000000040059a <+4>: sub [=10=]x10,%rsp
0x000000000040059e <+8>: movq [=10=]x400668,-0x8(%rbp)
0x00000000004005a6 <+16>: mov -0x8(%rbp),%rax
0x00000000004005aa <+20>: mov %rax,%rsi
=> 0x00000000004005ad <+23>: mov [=10=]x400675,%edi
0x00000000004005b2 <+28>: mov [=10=]x0,%eax
0x00000000004005b7 <+33>: callq 0x4004a0 <printf@plt>
0x00000000004005bc <+38>: mov [=10=]x0,%eax
0x00000000004005c1 <+43>: leaveq
0x00000000004005c2 <+44>: retq
C代码:
#include <stdio.h>
int main()
{
char *me = "abcdefghijkl";
printf("%s",me);
}
在概念层面上,我知道堆栈指针被减去以在堆栈上分配内存,然后不知何故,这是我在理解[的机制时遇到困难的部分=25=],程序创建字符串。
有人可以帮忙吗?
谢谢
如果你使用-S
标志到gcc
为你的程序创建一个程序集文件(gcc -S asm.c
),那就更清楚了。这会生成一个 asm.s
文件:
.file "asm.c"
.section .rodata
.LC0:
.string "abcdefghijkl"
.LC1:
.string "%s"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq , %rsp
movq $.LC0, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rsi
movl $.LC1, %edi
movl [=10=], %eax
call printf
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)"
.section .note.GNU-stack,"",@progbits
从这里可以看出,该字符串只是 .rodata
部分中分配了标签 .LC0
的一些初始化内存。更改内存会更改字符串。
我正在学习x86汇编语言。为了更好地理解字符串创建幕后发生的事情,我有一个示例程序,它只打印一个字符串。 GCC 生成了以下汇编程序,我无法理解编译器的输出:
汇编代码:
Dump of assembler code for function main:
0x0000000000400596 <+0>: push %rbp
0x0000000000400597 <+1>: mov %rsp,%rbp
0x000000000040059a <+4>: sub [=10=]x10,%rsp
0x000000000040059e <+8>: movq [=10=]x400668,-0x8(%rbp)
0x00000000004005a6 <+16>: mov -0x8(%rbp),%rax
0x00000000004005aa <+20>: mov %rax,%rsi
=> 0x00000000004005ad <+23>: mov [=10=]x400675,%edi
0x00000000004005b2 <+28>: mov [=10=]x0,%eax
0x00000000004005b7 <+33>: callq 0x4004a0 <printf@plt>
0x00000000004005bc <+38>: mov [=10=]x0,%eax
0x00000000004005c1 <+43>: leaveq
0x00000000004005c2 <+44>: retq
C代码:
#include <stdio.h>
int main()
{
char *me = "abcdefghijkl";
printf("%s",me);
}
在概念层面上,我知道堆栈指针被减去以在堆栈上分配内存,然后不知何故,这是我在理解[的机制时遇到困难的部分=25=],程序创建字符串。
有人可以帮忙吗? 谢谢
如果你使用-S
标志到gcc
为你的程序创建一个程序集文件(gcc -S asm.c
),那就更清楚了。这会生成一个 asm.s
文件:
.file "asm.c"
.section .rodata
.LC0:
.string "abcdefghijkl"
.LC1:
.string "%s"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq , %rsp
movq $.LC0, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rsi
movl $.LC1, %edi
movl [=10=], %eax
call printf
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)"
.section .note.GNU-stack,"",@progbits
从这里可以看出,该字符串只是 .rodata
部分中分配了标签 .LC0
的一些初始化内存。更改内存会更改字符串。