```@定义了一些辅助信息,比如:文件名,段名称
.
file
"main.c"
.text
.section .rodata
.align
32
.
type
encode, @
object
.size encode,
39
encode:
.string
"**************************************"
.text
.globl main @将main标记为全局可见的。
.
type
main, @function @声明main是一个函数。
main:
.LFB0:
.cfi_startproc @CFI (Call Frame Information)指令,用于生成调试信息。
endbr64 @对应特定的处理器指令,提供分支目标地址的溢出检测。
pushq
%
rbp
.cfi_def_cfa_offset
16
.cfi_offset
6
,
-
16
movq
%
rsp,
%
rbp
.cfi_def_cfa_register
6
subq $
16
,
%
rsp @rsp
=
rsp
-
16
@堆栈操作指令,用于保存和恢复寄存器的值。 上面除去CFI指令后是经典的开辟栈空间指令
movl $
0
,
-
4
(
%
rbp) @ [rbp
-
4
]
=
0
jmp .L2 @无条件跳转到L2处开始执行
@L5
由下文的分析可知道,这是个循环
.L5:
addl $
1
,
-
4
(
%
rbp) @[rbp
-
4
]
+
+
.L2:
movl
-
4
(
%
rbp),
%
eax @eax
=
[rbp
-
4
]
cltq @将eax寄存器的低
32
位符号扩展为
64
位,结果存储在rax寄存器中(在x86
-
64
中,eax是低
32
位的rax)。
leaq encode(
%
rip),
%
rdx @rdx
=
encode[rip] 就是将flag传给rdx
movzbl (
%
rax,
%
rdx),
%
eax @从以rax
+
rdx为基址的内存地址中读取一个字节,并将其零扩展为
32
位。然后将结果存储在eax寄存器中
movsbl
%
al,
%
ecx @ ECX
=
EAX
movl
-
4
(
%
rbp),
%
eax @ eax
=
[rbp
-
4
]
andl $
1
,
%
eax @ 判断奇偶性
testl
%
eax,
%
eax
je .L3 @ 若为偶数,则跳转到L3
movl
-
4
(
%
rbp),
%
eax @ eax
=
[rbp
-
4
]
subl $
1
,
%
eax @ eax
=
eax
-
1
cltq
leaq encode(
%
rip),
%
rdx @rdx
=
encode[rip]
movzbl (
%
rax,
%
rdx),
%
eax @eax
=
[rax
+
rdx] rax相当于下标i
movsbl
%
al,
%
eax
jmp .L4
.L3:
movl
-
4
(
%
rbp),
%
eax @eax
=
[rbp
-
4
]
.L4:
xorl
%
ecx,
%
eax @eax
=
eax ^ ecx
movl
%
eax,
%
edi @edi
=
eax
call putchar@PLT @putchar
movl
-
4
(
%
rbp),
%
eax @eax
=
[rbp
-
4
]
cltq
cmpq $
37
,
%
rax @
cmp
(
37
,rax)
jbe .L5 @rax<
37
则跳转到L5 ,继续循环
movl $
0
,
%
eax @eax
=
0
leave
.cfi_def_cfa
7
,
8
ret
.cfi_endproc
@一些调试信息
.LFE0:
.size main, .
-
main
.ident
"GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0"
.section .note.GNU
-
stack,"",@progbits
.section .note.gnu.
property
,
"a"
.align
8
.
long
1f
-
0f
.
long
4f
-
1f
.
long
5
0
:
.string
"GNU"
1
:
.align
8
.
long
0xc0000002
.
long
3f
-
2f
2
:
.
long
0x3
3
:
.align
8
4
: