我正在hacks.mozilla.org上阅读64位Firefox版本的博客.
作者说:
对于
asm.js代码,增加的地址空间还允许我们使用硬件内存保护来安全地从asm.js堆访问中删除边界检查.收益非常显着:asmjs-apps上的8%-17%- * - arewefastyet.com上报告的吞吐量测试.
我试图了解64位硬件如何对C/C++进行自动边界检查(假设编译器支持硬件).我在SO中找不到任何答案.我找到了一篇关于这个主题的技术论文,但我无法理解这是怎么做到的.
有人可以在边界检查中解释64位硬件辅助吗?
嗨,我已经拆解了一些程序(linux),我写的是为了更好地理解它是如何工作的,我注意到主要功能始终以:
lea ecx,[esp+0x4] ; I assume this is for getting the adress of the first argument of the main...why ?
and esp,0xfffffff0 ; ??? is the compiler trying to align the stack pointer on 16 bytes ???
push DWORD PTR [ecx-0x4] ; I understand the assembler is pushing the return adress....why ?
push ebp
mov ebp,esp
push ecx ;why is ecx pushed too ??
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:为什么所有这些工作都完成了?我只了解使用:
push ebp
mov ebp,esp
Run Code Online (Sandbox Code Playgroud)
其余对我来说似乎毫无用处......
注意这段代码:
#include <stdio.h>
void a(int a, int b, int c)
{
char buffer1[5];
char buffer2[10];
}
int main()
{
a(1,2,3);
}
Run Code Online (Sandbox Code Playgroud)
之后 :
gcc -S a.c
Run Code Online (Sandbox Code Playgroud)
该命令在程序集中显示我们的源代码.
现在我们可以在main函数中看到,我们从不使用"push"命令将函数的参数压入堆栈.它用"movel"而不是那个
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $3, 8(%esp)
movl $2, 4(%esp)
movl $1, (%esp)
call a
leave
Run Code Online (Sandbox Code Playgroud)
为什么会这样?他们之间有什么区别?
这是我不明白的两个问题:
One-Pass汇编程序如何解决未来的符号问题?
在这方面,双通道汇编程序与单通道汇编程序有何不同?
它是在第一次通过还是第二次通过时解决?如果它在第二遍中执行,它实际上与单通道汇编程序有什么不同?如果它在第二次传球中这样做,为什么不在第一次传球中呢?
我正在编写一个C代码,用于测量获取信号量所需的时钟周期数.我正在使用rdtsc,在对信号量进行测量之前,我连续两次调用rdtsc来测量开销.我在for循环中重复了这么多次,然后我将平均值用作rdtsc开销.
这是正确的,首先要使用平均值吗?
尽管如此,这里的一个大问题是,有时我会得到开销的负值(不一定是平均值,但至少是for循环中的部分值).
这也影响了连续计算sem_wait()操作所需的cpu周期数,有时也证明是负数.如果我写的不清楚,这里有一部分我正在编写的代码.
为什么我会得到这样的负值?
(编者注:请参阅获取CPU周期计数?以获得完整的64位时间戳的正确和可移植方式."=A"编译为x86-64时,asm约束只能得到低或高32位,具体取决于寄存器分配是否发生为uint64_t输出选择RAX或RDX .它不会选择edx:eax.)
(编辑的第二个注释:哎呀,这就是为什么我们得到负面结果的答案.仍然值得留下一个注释作为警告,不要复制这个rdtsc实现.)
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
static inline uint64_t get_cycles()
{
uint64_t t;
// editor's note: "=A" is unsafe for this in x86-64
__asm volatile ("rdtsc" : "=A"(t));
return t;
}
int num_measures = 10;
int main ()
{
int i, value, res1, res2;
uint64_t c1, c2;
int tsccost, tot, a;
tot=0;
for(i=0; i<num_measures; i++)
{ …Run Code Online (Sandbox Code Playgroud) 某些CPU(特别是x86 CPU)在其状态寄存器中具有奇偶校验标志.该标志指示操作结果的位数是奇数还是偶数.
奇偶校验标志在编程环境中起什么实际用途?
旁注: 我假设它打算与奇偶校验位一起使用以执行基本的错误检查,但是这样的任务似乎并不常见,以保证整个CPU标志.
我被告知要尝试使用'jmp而不是'call',但是'jmp'并不喜欢我..当我跳它不返回时(因此它永远不会退出并且不开心的日子),但是调用返回和退出正常.
我很高兴使用'呼叫',但实际上我有理由尝试克服'jmp'吗?
这个简单的代码只显示当我'jmp'时它永远不会返回并退出.
谢谢你提前获得任何帮助.
_start:
jmp _Print
jmp _Exit
ret
_Exit:
; normal exit
ret
_Print
; print something
ret
Run Code Online (Sandbox Code Playgroud)
另外..如果改变了什么,我在Linux终端中运行这一切
我有以下代码:
#include <stdio.h>
typedef struct {
bool some_var;
} model_t;
const model_t model = {
true
};
void bla(const model_t *m) {
if (m->some_var) {
printf("Some var is true!\n");
}
else {
printf("Some var is false!\n");
}
}
int main() {
bla(&model);
}
Run Code Online (Sandbox Code Playgroud)
我想编译器拥有消除函数else中的子句所需的所有信息bla()。调用该函数的唯一代码路径来自 main,并且它接受const model_t,因此它应该能够确定该代码路径未被使用。然而:
在 GCC 12.2 中,我们看到第二部分被链接进来。
如果我的inline功能这个消失了:
我在这里缺少什么?有什么方法可以让编译器做一些更智能的工作吗?在 C 和 C++ 中,使用-O3和都会发生这种情况-Os。
我将通过一些16位实模式的汇编代码示例.
我遇到过这样的问题:
mov bx, cs
mov ds, bx
mov si, OFFSET value1
pop es
mov di, OFFSET value2
Run Code Online (Sandbox Code Playgroud)
这是做什么的?"OFFSET"有什么作用?
我有一个带有一些库依赖项(.dll)的maven项目(我把它放在"lib"文件夹中).我可以在Netbeans中没有问题地运行项目,但是当我尝试在Netbeans之外运行构建的.jar时,我在加载库时遇到以下错误:
Can't load this .dll (machine code=0xbd) on a AMD 64-bit platform
我的计算机上只安装了一个 Java实例,它应该与Netbeans/Maven用于运行项目的JVM相同.所以我无法理解Netbeans/Maven如何在与我不同的平台上运行此应用程序?我已经尝试查看Netbeans执行的命令(从输出中)来运行项目,我认为是这样的:
cd C:\Users\Birger\Workspace\myproject; "JAVA_HOME=C:\\Program Files\\Java\\jdk1.8.0_91" cmd /c "\"\"C:\\Program Files\\NetBeans 8.1\\java\\maven\\bin\\mvn.bat\" -Dexec.args=\"-Djava.library.path=lib\\ -classpath %classpath com.mysite.myproject.Main\" -Dexec.executable=\"C:\\Program Files\\Java\\jdk1.8.0_91\\bin\\java.exe\" -Dmaven.ext.class.path=\"C:\\Program Files\\NetBeans 8.1\\java\\maven-nblib\\netbeans-eventspy.jar\" -Dfile.encoding=UTF-8 org.codehaus.mojo:exec-maven-plugin:1.2.1:exec\""
Run Code Online (Sandbox Code Playgroud)
我尝试了这两个命令
"C:\Program Files\Java\jdk1.8.0_91\jre\bin\java.exe" -Djava.library.path=lib\ -jar myproject-1.0-SNAPSHOT.jar
"C:\Program Files\Java\jdk1.8.0_91\bin\java.exe" -Djava.library.path=lib\ -jar myproject-1.0-SNAPSHOT.jar
Run Code Online (Sandbox Code Playgroud)
我添加System.out.println(System.getProperty("sun.arch.data.model"));了让我的应用程序打印出cpu架构.它可以64在两种场合下打印.
尝试查看"mvn.bat"文件,C:\Program Files\NetBeans 8.1\java\maven\bin\mvn.bat但我找不到任何关于Maven正在做什么来运行我的应用程序的线索.
有人可以帮我这个吗?
厄
编辑
这是我的测试项目的完整源代码.我的项目pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mysite</groupId>
<artifactId>myproject</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<repositories> …Run Code Online (Sandbox Code Playgroud)