当有人说"X服务器在/ dev/tty7上运行"时,我有几个问题.我对它是如何工作做了一些猜测,我希望有人可以告诉我以下陈述是真是假.
谢谢!
我已经读过一个double变量(8个字节)必须是8个字节对齐.
现在,如果我正在为我的程序编写整个代码,那么我可以使double变量8字节对齐而没有任何问题.
但是说我有以下场景:我创建了一个double在堆栈上创建变量的函数,并且我将此函数提供给其他人在他的程序中使用它.现在当我的函数被调用时,我的函数将不知道是否double将在可被8分割的地址上创建变量!
可以解决这个问题(请注意,我不关心不对齐我的double变量可以忽略的性能损失,但我只是想知道这个问题是否有解决方案)?
x86 CPU有一些处理整数和浮点数的指令.
例如:INC指令递增一个整数(可以存储在存储器或寄存器中)1,因此INC指令"知道"它应该将它正在操作的位解释为整数.那么我们可以说x86 CPU有数据类型(我们可以说C++有数据类型)吗?或者为了让我们能够说出来,x86 CPU应该提供类型安全等其他功能(它没有提供)?
我在 NASM的.data部分定义了以下变量:
section .data
var1 DD 12345 ; int (4 bytes)
var2 DB 'A' ; char (1 byte)
padding1 DB 123 ; 1 byte padding
padding2 DB 123 ; 1 byte padding
padding3 DB 123 ; 1 byte padding
var3 DQ 174.13 ; double (8 bytes)
Run Code Online (Sandbox Code Playgroud)
为了正确对齐这些变量,.data部分必须对齐到 8 个字节。
我相信.data部分的对齐方式是由链接器指定的。我正在使用 Visual C++ 2010 链接器,如何使用此链接器设置.data部分的对齐方式?
我已经在gcc中成功编译并执行了以下代码:
#include <stdio.h>
int foo()
{
}
int main()
{
int i = 12345;
i = foo();
printf("i is: %d", i);
}
Run Code Online (Sandbox Code Playgroud)
输出是:
i is: 0
Run Code Online (Sandbox Code Playgroud)
所以gcc允许我不从函数返回foo()并foo()返回0.
这种行为只适用于gcc还是其他C标准也有它(基于我的理解,gcc不符合任何C标准)?
如果我在Drupal 8中有两种内容类型与它们之间存在关系,为了表示关系,我可以将引用字段放在这两种内容类型之一中的另一种内容类型中.
但在本视频教程中,它显示了两个内容类型彼此包含引用字段的示例.
在什么情况下我想在两种内容类型中都放置一个引用字段?
我已经读过,如果某些CPU试图访问未对齐的数据,它们将产生异常.
基于我做的测试,x86 CPU在尝试访问未对齐数据时没有产生异常,但我想知道是否存在未对齐数据会导致x86 CPU产生异常的情况?
我正在NASM中编写程序,我不想将它与CRT链接,因此我将指定入口点(这将是Win32入口点).这是程序源代码:
global _myEntryPoint
section .text
_myEntryPoint:
mov eax, 12345
Run Code Online (Sandbox Code Playgroud)
现在这就是我对Win32入口点的了解(如果我错了请纠正我):
ExitProcess()).现在我不知道的是以下内容:
我试图了解寄存器必须被称为"通用寄存器"的标准.
我认为通用寄存器是一个寄存器,可以用于任何事情(用于计算,向/从它移动数据等),并且是一个没有特殊用途的寄存器.
现在我已经读到ESP寄存器是通用寄存器.我想ESP寄存器可以用于任何东西,但ESP寄存器也有一个特殊的用途,即指向堆栈的顶部.
这是否意味着ESP寄存器是一个特殊目的寄存器?
我有时会在关于内存排序的教程中看到术语"完全内存屏障",我认为这意味着以下内容:
如果我们有以下说明:
instruction 1
full_memory_barrier
instruction 2
Run Code Online (Sandbox Code Playgroud)
然后instruction 1不允许重新排序到下面full_memory_barrier,并且instruction 2不允许重新排序到上面full_memory_barrier.
但是完全内存屏障的反面是什么,我的意思是有什么像"半内存屏障"只能阻止CPU在一个方向上重新排序指令?
如果有这样的记忆障碍,我没有看到它的意思,我的意思是如果我们有以下指示:
instruction 1
memory_barrier_below_to_above
instruction 2
Run Code Online (Sandbox Code Playgroud)
假设这memory_barrier_below_to_above是一个阻止instruction 2重新排序到上面的内存屏障memory_barrier_below_to_above,因此不允许以下内容:
instruction 2
instruction 1
memory_barrier_below_to_above
Run Code Online (Sandbox Code Playgroud)
但是允许以下内容(这使得这种类型的内存屏障毫无意义):
memory_barrier_below_to_above
instruction 2
instruction 1
Run Code Online (Sandbox Code Playgroud) 该mfence 文件说以下内容:
对MFENCE指令之前发出的所有内存加载和存储到内存指令执行序列化操作.此序列化操作保证在遵循MFENCE指令的任何加载或存储指令之前,按程序顺序在MFENCE指令之前的每个加载和存储指令都变为全局可见.
据我所知,x86中没有fence指令可以防止非读取和非写入指令的重新排序.
现在如果我的程序只有一个线程,即使指令被重新排序,它仍然看起来好像指令正在按顺序执行.
但是,如果我的程序有多个线程,并且在其中一个线程中非读取和非写入指令被重新排序,其他线程会注意到这个重新排序(我假设答案是否定,否则会有一个fence指令停止非读取和非写入指令重新排序,或者我可能缺少某些东西)?
据我所知,函数调用充当编译器障碍,但不作为CPU障碍.
本教程说明如下:
获取锁意味着获取语义,而释放锁意味着释放语义!其间的所有内存操作都包含在一个漂亮的小屏障三明治中,防止任何不希望的内存重新排序跨越边界.
我假设上面的引用是关于CPU重新排序而不是编译器重新排序.
但我不明白互斥锁和解锁如何导致CPU赋予这些函数获取和释放语义.
例如,如果我们有以下C代码:
pthread_mutex_lock(&lock);
i = 10;
j = 20;
pthread_mutex_unlock(&lock);
Run Code Online (Sandbox Code Playgroud)
上面的C代码被翻译成以下(伪)汇编指令:
push the address of lock into the stack
call pthread_mutex_lock()
mov 10 into i
mov 20 into j
push the address of lock into the stack
call pthread_mutex_unlock()
Run Code Online (Sandbox Code Playgroud)
现在是什么阻止了CPU重新排序mov 10 into i以及mov 20 into j 上方call pthread_mutex_lock()或下方call pthread_mutex_unlock()?
如果它是call阻止CPU进行重新排序的指令,那么为什么我引用的教程使它看起来像是互斥锁和解锁函数来阻止CPU重新排序,为什么我引用的教程没有说任何函数调用会阻止CPU重新排序吗?
我的问题是关于x86架构.