今天出现了一些奇怪的事情.当我想用旧的方式在C(C++)中保存一些字符串时,不使用字符串头,我只是创建数组并将该字符串存储到其中.但是,我读到在本地功能范围内C中的任何变量定义最终都会将这些值推送到堆栈中.
因此,字符串实际上比需要的大2倍.因为首先,推送指令位于存储器中,但是当它们被执行(推入堆栈)时,创建了字符串的另一个"副本".首先是推送指令,而不是堆栈空间用于一个字符串.
那么,为什么会这样呢?为什么编译器只是将字符串(或其他变量)添加到程序中而不是在执行时再次创建它们?是的,我知道你不能只在程序块中有一些数据,但它可能只是附加到程序的末尾,之前有一些跳转指令.而且,我们只是指出这些数据?因为它们在执行程序时存储在RAM中.
谢谢.
我有2个简单但也许棘手的问题.假设我有汇编指令:MOV EAX,[ebx + 6*7] - 我很好奇的是,这条指令实际上是否实际转换为操作码,因此括号中的代码计算被编码为操作码,或者这只是编译器的伪指令,而不是CPU,所以编译器在使用add mul计算括号中的值之前,在某些reg中存储结果,而不是使用MOV EAX,reg与计算值?为了清楚起见,我知道输出会是一样的.我对执行感兴趣.
其次是关于LEA指令.我知道它的作用,但是我对它的实际指令更感兴趣,因此编译不会进一步改变它,只是将其变为操作码,或者只是编译器的伪代码,再次首先计算地址而不是存储它.
我很长一段时间试图了解如何在OS下处理程序内存(我使用Windows,但我想这在Linux上会是相同或非常接近).
到目前为止,我知道(主要是感谢stackoverflow用户)局部变量存储在堆栈中.现在我终于明白了为什么.那没关系.
但我仍然想念的是,如何存储和处理全局变量.我想在汇编的基础上知道它.我知道如何处理这些问题,但我无法确定,因为有许多事情我还不知道,这可能使我的想法无法实现.
所以,我的想法是,全局变量位于程序代码的末尾.在最后一条指令之后.为什么我认为它可能是这样的?比起来,你不需要浪费任何额外的内存和CPU时间.因为执行时操作系统将变量及其默认值复制到RAM中.
为什么我认为这是可能的?如果我没有错,那么在现代x86操作系统上,每个程序从0开始都有自己的地址空间.这样,编译非常容易知道全局变量的地址.因为它知道程序的长度,所以它可以计算它在地址空间中的位置.
为什么我认为这可能都错了?Becouse我已经想到为什么在堆栈上创建局部变量的方式相同.当你有一些ELF格式的例程时,你有预编译的例程,只有未解决的变量地址.
另外,在一些文章中,我读到使用malloc分配内存扩展堆.因为我把堆作为程序代码之后的空格,会有错误因为它会成长为堆栈.否则堆栈将需要位于进程地址空间的末尾,但是taht将是可怕的内存浪费.
我试图尽可能多地描述我的观点,所以我希望你能理解我犯了哪些错误,并帮助我填补我所缺少的知识.谢谢.
有没有办法将 Avatar 组件与 MaterialUI 组件一起放在 Toolbar 中?
<Toolbar>
<ToolbarGroup float="right" lastChild>
<ToolbarTitle text="Toolbar"/>
<Avatar src="images/avatar.jpg"/>
</ToolbarGroup>
</Toolbar>
Run Code Online (Sandbox Code Playgroud)
我玩了这几个小时但没有成功。
是否可以使用spring.cloud.function具有多个独立函数/绑定的函数式( ) 样式的反应式 SCS 应用程序?我发现的所有示例总是只注册一个具有默认绑定的功能性 bean input, output。我想注册多个,每个都有自己的绑定。
传统上可以使用spring-cloud-stream-reactive它来完成,但现在不赞成使用功能支持。
我知道这是一个更"沉重"的问题,但我认为它也很有趣.这是我之前关于编译器功能的问题的一部分,但是我回答的非常糟糕,许多人回答了我的第一个问题,所以它是:
因此,如果我的知识是正确的,现代Windows系统使用分页作为切换任务的方式,并保证每个任务都在内存中占有一席之地.因此,每个流程从0开始都有自己的位置.
当多任务处理生效时,内核必须将所有重要的寄存器保存到任务堆栈我相信比保存当前堆栈指针,更改页面条目以切换到另一个进程的物理地址空间,加载新进程堆栈指针,弹出保存通过调用poped指令指针地址来注册并继续.
对于这个不错的功能(分页)而言,每个进程都认为它具有良好的平坦内存.因此,没有远端跳转,远指针,内存段或数据段.一切都很好,线性.
但是,当流程没有更多细分时,为什么编译器仍然在堆栈上创建变量,或者直接在其他内存空间中创建变量,而不是直接在程序代码中?
让我举个例子,我有一个C代码:int a=10;
它被翻译成(英特尔语法):mov [position of a],#10
但实际上,你实际上在RAM中的字节数比需要的多.Becouse,前几个字节接受actuall指令,在该指令完成后,有一个包含值10的新字节.
为什么,而不是这个,当不需要切换任何段(从而减慢处理速度)时,不仅仅是10的值直接编码到程序中,如下所示:
xor eax,eax //just some instruction
10 //the value iserted to the program
call end //just some instruction
Becouse编译器知道每条指令的确切位置,当使用该变量操作时,它只会使用它的地址.
我知道,const变量可以做到这一点,但是当你无法改变它们时,它们不是真正的变量.
我希望我能很好地解释我的问题,但我仍然在学习英语,所以请原谅我的同情甚至是语义上的错误.
编辑:
我已经阅读了你的答案,似乎基于那些我可以修改我的问题:
所以,有人告诉我,全局变量实际上是直接附加到程序中的那一段值,我的意思是,当变量是全局变量时,它是在程序结束时,还是在执行时就像本地变量一样创建,但是而不是直接在堆上堆栈?
如果第一种情况 - 附加到程序本身,为什么甚至存在局部变量?我知道,你会告诉我因为递归,但事实并非如此.当你调用函数时,你可以在堆栈上推送任何内存空间,因此那里没有程序.
我希望你理解我,当某些指令在堆栈上创建一些值(甚至为0)时,总是会无法使用内存,因为你需要在程序中为该指令而不是实际的var.像这样:push #5 //instruction that says to create local variable with integer 5
并且比这个指令只让第5个堆栈.请帮帮我,我真的很想知道为什么会这样.谢谢.
我对OOP知之甚少,所以也许我的问题很愚蠢,但仍然......
您可以从过程(非OO)语言访问面向对象(OO)的API吗?例如,Win32 API不是OO,但我知道有一个C++的包装器可以使它成为OO.但是有可能两种方式吗?
我问,因为我不喜欢OO语言; 我通过编程微控制器来学习C语言,而OO语言只是将实际的代码从你身上移开,我担心OOP如此受欢迎,很快一切都将基于对象.
好的,我相信你们中的一些人已经知道我的头衔是怎么回事,因为我觉得这是非常常见的问题.但我的问题实际上更深一点,所以请耐心等待我.
我过去几年所做的所有编程都在Assembler中,主要是8051,AVR和C一样,但也适用于微控制器.我对HW比SW更着迷.但我也对OS的功能,它的API等着迷.几天后我告诉我的朋友,如果你有数学解析器,创建一个非常简单的程序绘制函数图应该很容易.他不相信我,所以我试图制作一个.
我决定使用C#,即使我不了解OOP.但我认为,如果我在一个按钮动作中完成所有操作,那就像是老C一样.
所以我让数学解析器工作,然后开始使用Pen对象绘制.我的第一次尝试是绘制简单的线条.在阅读了一个教程之后,我设法这样做,并为我的情节创建了简单的轴.
但是,当我最小化我的程序时,我发现了一些奇怪的东西.这让我想一想如何在系统级别完成所有绘图.
我认为系统保持活动窗口的图像直到它改变了.所以当你移动你的窗户时,它只会改变它在famebuffer中的位置.当你最小化它时,它只是在drawind到framebuffer时跳过它.
但我看到它不是这样的.那么,拜托,你能告诉我为什么会这样吗?我可以在许多教程中阅读如何防止它,但我想知道更多原因.更多,这是因为系统API如何工作,或者因为C#绘图类是如何工作的.
此外,这让我想到C#和.NET库中的功能只是调用WinAPI函数,它的工作方式完全相同,以及有多少库和函数执行更多操作.就像在GDI中没有绘制线条的功能一样,你只能画点,而C#会添加从这个点画线的功能.我希望你能理解我.
谢谢.
我已经在这里问了类似的问题,但我仍然有一些错误,所以我希望你能告诉我我做错了什么.只知道我知道汇编程序,并且我在8051汇编程序中完成了几个项目,即使它不一样,也接近于x86 asm.
我在VC++ 2010 Express中试过一段代码(我试图从CPUID指令中获取信息):`
int main()
{
char a[17]; //containing array for the CPUID string
a[16] = '\0'; //null termination for the std::cout
void *b=&a[0];
int c=0; //predefined value which need to be loaded into eax before cpuid
_asm
{
mov eax,c;
cpuid;
mov [b],eax;
mov [b+4],ebx;
mov [b+8],ecx;
mov [b+12],edx;
}
std::cout<<a;
}`
Run Code Online (Sandbox Code Playgroud)
因此,为了快速总结,我尝试创建指向数组第一个元素的void指针,而不是使用间接寻址只是从寄存器移动值.但是这种方法让我"堆栈b变量是运行时错误",但我不知道为什么.
请帮忙.谢谢.这只是为了研究目的,我知道有CPUID的功能....
编辑:另外,如何在x86 VC++ 2010内联汇编程序中使用直接寻址?我的意思是8051中立即数字加载的常用语法是mov src,#numberVC++ asm,mov dest,number没有#符号.那么如何告诉编译器你想直接访问内存单元地址x?
我想用Java创建简单的聊天程序,它可以在p2p的基础上工作.使用公共服务器仅启动连接.但我甚至不确定这是可能的.
我成功地实现了Java中的聊天解决方案,如果至少有一台PC转发了正确的端口,那么它就可以工作.我还设法使用外部服务器而不必在客户端转发端口.
因此,我甚至可能以某种方式使用公共服务器启动连接,而不是在客户端之间发送数据,从服务器上卸载?
我不太熟悉路由器如何工作,但我希望当你从内部IP呼叫公共服务器时,路由器会记住来自该公共IP的呼叫和传入响应,而不是发送到你的PC.所以我想,也许如果第一个客户端连接到服务器,服务器而不是将信息传递给第二个客户端,也许他们可以以某种方式直接通信?路由器中的规则是否由服务器建立?
我希望我能清楚地解释清楚.如果没有,请原谅.我甚至都不知道这是怎么做到的,我只是想知道我的概念是否有正确的东西,而且我必须更加努力地学习它.谢谢.