我遇到了一个没有 libc 的最小 HTTP 服务器:https : //github.com/Francesco149/nolibc-httpd
我可以看到定义了基本的字符串处理函数,导致write系统调用:
#define fprint(fd, s) write(fd, s, strlen(s))
#define fprintn(fd, s, n) write(fd, s, n)
#define fprintl(fd, s) fprintn(fd, s, sizeof(s) - 1)
#define fprintln(fd, s) fprintl(fd, s "\n")
#define print(s) fprint(1, s)
#define printn(s, n) fprintn(1, s, n)
#define printl(s) fprintl(1, s)
#define println(s) fprintln(1, s)
Run Code Online (Sandbox Code Playgroud)
基本的系统调用在 C 文件中声明:
size_t read(int fd, void *buf, size_t nbyte);
ssize_t write(int fd, const void *buf, size_t nbyte);
int open(const char *path, int flags); …Run Code Online (Sandbox Code Playgroud) 我知道 ODR、链接、static和如何extern "C"与函数配合使用。但我不确定类型的可见性,因为它们无法声明static,并且 C 中没有匿名名称空间。
特别是,我想知道以下代码如果编译为 C 和 C++ 的有效性
// A.{c,cpp}
typedef struct foo_t{
int x;
int y;
} Foo;
static int use_foo()
{
Foo f;
f.x=5;
return f.x;
}
Run Code Online (Sandbox Code Playgroud)
// B.{c,cpp}
typedef struct foo_t{
double x;
} Foo;
static int use_foo()
{
Foo f;
f.x=5.0;
return f.x;// Cast on purpose
}
Run Code Online (Sandbox Code Playgroud)
使用以下两个命令(我知道两个编译器都会根据扩展自动检测语言,因此名称不同)。
g++ -std=c++17 -pedantic -Wall -Wextra a.cpp b.cppgcc -std=c11 -pedantic -Wall -Wextra a.c b.c8.3 版本可以愉快地编译两者,没有任何错误。显然,如果两个结构符号都具有外部链接,则存在 ODR 违规,因为定义不相同。是的,编译器不需要报告它,因此我的问题是因为两者都没有报告。
什么(如果有的话)是x86 asm xchg指令的C#等价物?
有了这个命令,哪个imo是一个真正的交换(不像Interlocked.Exchange),我可以简单地自动交换两个int,这就是我真正想做的事情.
更新:
示例代码基于我的建议.变量后缀"_V"被装饰为volatile:
// PART 3 - process links
// prepare the new Producer
address.ProducerNew.WorkMask_V = 0;
// copy the current LinkMask
address.ProducerNew.LinkMask_V = address.Producer.LinkMask_V;
// has another (any) thread indicated it dropped its message link from this thread?
if (this.routerEmptyMask[address.ID] != 0)
{
// allow all other bits to remain on (i.e. turn off now defunct links)
address.ProducerNew.LinkMask_V &= ~this.routerEmptyMask[address.ID];
// reset
this.routerEmptyMask[address.ID] = 0;
}
// PART 4 - swap
address.ProducerNew = …Run Code Online (Sandbox Code Playgroud) 0x0000000000400553 <main+59>: mov -0x4(%rbp),%eax
0x0000000000400556 <main+62>: cltq
0x0000000000400558 <main+64>: shl $0x3,%rax
0x000000000040055c <main+68>: mov %rax,%rdx
Run Code Online (Sandbox Code Playgroud)
事实上,我的程序很简单:
5 int main(int argc, char *argv[]) {
6 int i = 0;
7 while(environ[i]) {
8 printf("%s\n", environ[i++]);
9 }
10 return 0;
Run Code Online (Sandbox Code Playgroud)
但是程序集输出很长:
Dump of assembler code for function main:
0x0000000000400518 <main+0>: push %rbp
0x0000000000400519 <main+1>: mov %rsp,%rbp
0x000000000040051c <main+4>: sub $0x20,%rsp
0x0000000000400520 <main+8>: mov %edi,-0x14(%rbp)
0x0000000000400523 <main+11>: mov %rsi,-0x20(%rbp)
0x0000000000400527 <main+15>: movl $0x0,-0x4(%rbp)
0x000000000040052e <main+22>: jmp 0x400553 <main+59>
0x0000000000400530 <main+24>: mov -0x4(%rbp),%eax …Run Code Online (Sandbox Code Playgroud) 我试图理解汇编语言如何适用于微计算机体系结构类,并且我在示例中仍然面对不同的语法:
sub $48, %esp
mov %eax, 32(%esp)
Run Code Online (Sandbox Code Playgroud)
这些代码是什么意思?什么是32操作数和esp寄存器的添加?
好吧,我知道CLD清除方向标志和STD设置方向标志.但是设置和清除方向标志的重点是什么?
我正在尝试在两种算法之间做出决定.一个写入8个字节(两个对齐的4字节字)到2个高速缓存行,另一个写入3个整个高速缓存行.
如果CPU只将更改的8个字节写回内存,则第一个算法使用的内存带宽要少得多:8个字节对192个字节.如果CPU写入整个高速缓存行,则128和192字节之间的差异不那么显着.
那么Intel Xeon CPU如何写回内存?你会惊讶地发现在谷歌找到一个应该众所周知的答案是多么困难.
据我了解,写入进入存储缓冲区,然后进入缓存.当脏缓存行从缓存中逐出时,它们可能只被写入内存,但是英特尔是否跟踪缓存行的哪些部分是脏的,或者只是转储整个内容?我更怀疑他们跟踪缓存行粒度以下的事情.如果在高速缓存行被驱逐之前有任何事情进入内存,我也会感到非常惊讶.
你能否告诉我JUMP如果上面和JUMP如果大会用汇编语言?我什么时候使用它们?他们给我不同的结果吗?
我想尝试使用SIMD指令编写atoi实现,包含在RapidJSON(C++ JSON 读 /写库)中.它目前在其他地方有一些SSE2和SSE4.2优化.
如果是速度增益,atoi则可以并行执行多个结果.字符串最初来自JSON数据的缓冲区,因此多atoi函数将不得不进行任何所需的调配.
我想出的算法如下:
我的目标是x86和x86-64架构.
我知道AVX2支持三个操作数Fused Multiply-Add,所以我将能够执行Sum = Number*有效数字+和.
那是我到目前为止的地方.
我的算法是否正确?有没有更好的办法?
是否有使用任何SIMD指令集的atoi参考实现?
我最近在回答一个关于p < q当p和q是指向不同对象/数组的指针时在C 中执行的未定义行为的问题。这让我想到:C ++ <在这种情况下具有相同(未定义)的行为,但是还提供了标准库模板std::less,该模板保证可以返回与<可以比较指针时相同的东西,并在不能比较时返回一些一致的顺序。
C是否提供具有类似功能的东西,从而可以安全地比较任意指针(相同类型)?我尝试浏览C11标准并没有发现任何东西,但是我在C中的经验比在C ++中小得多,因此我很容易错过一些东西。
c pointers memory-model undefined-behavior memory-segmentation