为什么cabal install默认情况下不使用标志--enable-shared?我注意到,在没有这个标志的情况下编译的琐碎程序,文件大小会很大.有连接吗?这是一个与Haskell程序如何在一个独立的二进制文件中轻松部署相关的设计选择吗?
我有一个C++库,可以生成更大的代码,我真的期望它正在做什么.从不到50K的源代码行中,我获得了大约4 MB的共享对象和静态归档推送9.这是有问题的,因为库二进制文件非常大,更糟糕的是,甚至连接它的简单应用程序通常会获得500到1000 KB代码大小.使用像-Os这样的标志编译库有点帮助,但不是很多.
我还尝试了GCC的-frepo命令(尽管我见过的所有文档都表明Linux上的collect2将会合并重复的模板)和模板上的显式模板实例化似乎"可能"重复很多,但是没有两种情况都有实际效果.当然,我说"可能",因为,与任何类型的剖析一样,这样的盲目猜测几乎总是错误的.
是否有一些工具可以轻松地分析代码大小,或者其他一些方法我可以找出占用这么多空间的东西,或者更一般地说,我应该尝试的其他任何东西?在Linux下工作的东西是理想的,但我将采取我能得到的东西.
我正在查看汇编中的不同指令,我对如何决定不同操作数和操作码的长度感到困惑.
这是你应该从经验中得知的东西,还是有办法找出哪个操作数/运算符组合占用了多少字节?
例如:
push %ebp ; takes up one byte
mov %esp, %ebp ; takes up two bytes
Run Code Online (Sandbox Code Playgroud)
所以问题是:
在看到给定的指令后,如何推断出其操作码需要多少字节?
来自Scott Meyers的Effective C++:
template<typename T, std::size_t n>
class SquareMatrix: private SquareMatrixBase<T> {
public:
SquareMatrix( )
: SquareMatrixBase<T>(n, 0),
pData(new T[n*n])
{
this->setDataPtr(pData.get());
}
...
private:
boost::scoped_array<T> pData;
};
Run Code Online (Sandbox Code Playgroud)
无论数据存储在何处,从膨胀的角度来看,关键结果是,现在很多 - 也许全部 - SquareMatrix的成员函数可以是对基类版本的简单内联调用,这些基类版本与所有其他具有相同类型的矩阵共享数据,无论其大小.同时,不同大小的SquareMatrix对象是不同的类型,所以即使例如SquareMatrix <double,5>和SquareMatrix <double,1 0>对象在SquareMatrixBase <double>中使用相同的成员函数,也没有机会将SquareMatrix <double,5>对象传递给期望SquareMatrix <double,1 0>的函数.很好,不是吗?
很好,是的,但不是免费的.具有硬连线的矩阵大小的反转版本可能比共享版本生成更好的代码,其中大小作为函数参数传递或存储在对象中.例如,在特定于大小的版本中,大小将是编译时常量,因此有资格进行常量传播等优化,包括将它们作为立即操作数折叠到生成的指令中.这不能在与大小无关的版本中完成.
在上一段的上述描述中,它被称为"因此有资格进行恒定传播等优化,包括将它们作为立即操作数折叠到生成的指令中".这个陈述是什么意思?请来解释一下.
谢谢!
什么是最短的Intel x86-64操作码设置rax为1?
我试着xor rax,rax和inc al(在NASM语法); 它给出了5字节的操作码48 31 c0 fe c0.是否有可能以4个字节实现相同的结果?
您可以修改或读取任何其他寄存器,但不能假设特定值将来自之前的指令中的任何一个.
我正在学习一些有趣的汇编程序,并且我可能太绿了,无法知道正确的术语并自己找到答案。
我想在程序末尾打印换行符。
下面工作正常。
section .data
newline db 10
section .text
_end:
mov rax, 1
mov rdi, 1
mov rsi, newline
mov rdx, 1
syscall
mov rax, 60
mov rdi, 0
syscall
Run Code Online (Sandbox Code Playgroud)
但是我希望在不定义.data换行符的情况下实现相同的结果。是否可以sys_write直接使用所需的字节进行调用,还是必须始终通过引用一些预定义的数据来完成调用(我认为这mov rsi, newline是在做什么)?
简而言之,为什么我不能替换mov rsi, newline为mov rsi, 10?
在速度,性能和机器代码大小方面哪种格式更好?
最后return封装:
static bool MyClass::IsEqual(int A, int B)
{
if (A == B)
{
return true;
}
else
{
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
最后return没有封装:
static bool MyClass::IsEqual(int A, int B)
{
if (A == B)
{
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud) 我有一个没有MMU的微控制器,但我们使用的是C和C++.
我们避免使用所有动态内存(即没有new SomeClass()或malloc())和大多数标准库.
半问题0:
据我所知std::array,不使用任何动态内存,所以它的用法应该没问题(它只在堆栈上).查看std::array源代码,它看起来很好,因为它创建了一个c风格的数组,然后围绕该数组包装功能.
我们使用的芯片有1MB的闪存用于存储代码.
问题1:
我担心使用模板std::array会导致二进制文件变大,这可能会导致二进制文件超过1MB的代码内存限制.
我想如果你创建一个a的实例std::array< int, 5 >,那么所有对函数的调用std::array都将占用一定数量的代码内存,让我们说X字节的内存.
如果你创建了另一个实例std::array< SomeObject, 5 >,然后调用函数,那么std::array现在每个函数都会在二进制文件中重复,从而占用更多的代码内存吗?X字节的内存+ Y字节的内存.
如果是这样,您认为在有限的代码内存容量下生成的代码量是一个问题吗?
问题2:
在上面的示例中,如果您创建了第二个std::array< int, 10 >实例,对函数的调用是否也会复制生成的代码中的函数调用?尽管这两种情况都是同一类型的,int?
当将x设置为零(x = 0)时,我的csapp书指出了两种方法。
第一:
xorq %rcx, %rcx
Run Code Online (Sandbox Code Playgroud)
第二:
movq $0, %rcx
Run Code Online (Sandbox Code Playgroud)
它还表明第一个仅占用3个字节,而第二个仅占用7个字节。
两种方式如何运作?为什么第一个字节比第二个字节少?
在嵌入式系统上工作时,每个字节的内存都很重要,在C/C++程序中,当你使用4个空格而不是1个选项卡时,结果代码大小有什么不同吗?
下面的代码占用 20 个字节。然而,有一种方法可以通过中断使其变得更小。如何?
\nA\nMOV AH,9\nMOV DX,108\nINT 21\nRET\nDB 'HELLO WORLD$'\n\nR CX\n14\nN MYHELLO.COM\nW \nRun Code Online (Sandbox Code Playgroud)\n code-size ×11
assembly ×5
c++ ×4
x86-64 ×3
linux ×2
machine-code ×2
templates ×2
c ×1
c++11 ×1
deployment ×1
dos ×1
gcc ×1
haskell ×1
if-statement ×1
memory ×1
nasm ×1
optimization ×1
performance ×1
space ×1
stdarray ×1
tabs ×1
x86 ×1
x86-16 ×1