我编写了以下代码:
// a.c
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
_Noreturn void _start()
{
register int syscall_num asm ("rax") = __NR_exit;
register int exit_code asm ("rdi") = 0;
// The actual syscall to exit
asm volatile ("syscall"
: /* no output Operands */
: "r" (syscall_num), "r" (exit_code));
}然后使用clang-7 -Oz -pipe -flto -c a.c进行编译,并使用llc-7 -filetype=asm a.o将其转换为人类可读的汇编文件a.o.s。
.text
.file "a.c"
.globl _start # -- Begin function _start
.type _start,@function
_start: # @_start
.cfi_startproc
# %bb.0:
pushq $60
.cfi_adjust_cfa_offset 8
popq %rax
.cfi_adjust_cfa_offset -8
xorl %edi, %edi
#APP
syscall
#NO_APP
retq
.Lfunc_end0:
.size _start, .Lfunc_end0-_start
.cfi_endproc
# -- End function
.ident "clang version 7.0.1-svn348686-1~exp1~20181211133235.57 (branches/release_70)"
.section ".note.GNU-stack","",@progbits在上面的程序集中,指令#APP出现在syscall前面,这是我编写的程序集,而指令#NO_APP就出现在它后面。
我知道它一定与asm的使用有关,比如防止它被优化,但是在googling搜索之后我找不到它的任何文档。
谢谢你提前了。
发布于 2018-12-28 14:04:44
至少在历史上,编译器告诉as,它可以使用一种快速解析模式来解析纯编译器的输出,然后从内联-asm切换回来对块进行完整的解析。在文件的早期位置应该有一个进入此模式的#APP。#NO_APP将退出此模式。
我不确定as用这个提示做了什么,所以它甚至可能根本不寻找#NO_APP,而只是像对待其他评论一样对待它。
在实践中,它分隔来自内联模板的文本块,而编译器则生成asm。除此之外,它不会做任何事情,而且如果您出于某种原因手工编辑asm,则完全可以找到删除它的方法。
发布于 2022-08-11 08:48:37
这些宏禁用(#NO_APP)或启用(#APP)预处理器,允许在不需要预处理器时禁用预处理器,从而加快解析速度。
从煤气手册上,
如果输入文件的第一行是“#NO_APP”,或者使用“-f”选项,则不会从输入文件中删除空白和注释。在输入文件中,您可以通过在可能包含空白或注释的文本之前放置一行“#APP”,并在文本后面放置一行“#NO_APP”,请求在输入文件的特定部分删除空白和注释。这个特性主要是为了支持编译器中的'asm‘语句,否则其输出没有注释和空格。
您可以在有关-f选项的部分中找到此警告:
警告:如果在文件实际需要预处理时使用'-f‘(例如,如果其中包含注释),则'as’不能正确工作。
发布于 2018-12-28 13:56:20
它移除空白和它与#NO_APP之间的注释。
在本例中,它放在这里是为了防止在asm()中有注释
https://stackoverflow.com/questions/53959565
复制相似问题