这不是一个微不足道的问题.
注意:我不需要意见或建议使用纯asm.我实际上需要完成我正在谈论的内容:在将结果分配给short int时,在没有此符号的情况下获取内联asm /零扩展optcode.
我正在处理一个滥用16位短路的库,我正在优化它.我需要使用内联asm添加一些优化函数.问题是在很多地方将函数的结果赋给short int.也就是说,编译器生成第u个或第s个arm操作码.
我的目标是避免这个问题,并确保不会生成这个无用的操作码.首先,我需要定义我的优化函数来返回short int.这样,如果将其分配给int或short int,则不会有额外的操作码来转换结果.
问题是我不知道如何跳过编译器在我自己的函数中生成的int-> short转换.
愚蠢的演员:*(short*)(void*)&value不起作用.编译器要么开始更多地解决堆栈制作问题,要么仍然使用相同的sxth来对结果进行签名扩展.
我为多个编译器编译,我能够为arm的armcc编译器解决它,但我不能用GCC完成它(我用4.4.3或4.6.3编译).使用armcc我在内联asm语句中使用短类型.在gcc中,即使我使用短编译器仍因某种原因认为需要符号扩展.
这是一个简单的代码片段,我无法与GCC合作,有关如何使其工作的任何建议?对于这个简单的例子,我将使用clz指令:
示例文件test.c文件:
static __inline short CLZ(int n)
{
short ret;
#ifdef __GNUC__
__asm__("clz %0, %1" : "=r"(ret) : "r"(n));
#else
__asm { clz ret, n; }
#endif
return ret;
}
//test function
short test_clz(int n)
{
return CLZ(n);
}
Run Code Online (Sandbox Code Playgroud)
这是我用armcc -c -O3得到的预期结果:
test_clz:
CLZ r0,r0
BX lr
Run Code Online (Sandbox Code Playgroud)
这是GCC -c -O3给我的不可接受的结果:
test_clz:
clz r0, r0
sxth r0, r0
bx lr
Run Code Online (Sandbox Code Playgroud)
另请注意,如果使用内部变量int ret;而不是 …
#define PP_ARG0_(arg0, ...) arg0
#define PP_REST_(arg0, ...) __VA_ARGS__
#define PP_ARG0(args) PP_ARG0_ args
#define PP_REST(args) PP_REST_ args
#define FUNCTION(name) void name();
#define FUNCTION_TABLE(...) \
FUNCTION(PP_ARG0((__VA_ARGS__))) \
FUNCTION_TABLE(PP_REST((__VA_ARGS__))) \
Run Code Online (Sandbox Code Playgroud)
测试代码:
FUNCTION_TABLE(f1, f2,f3,testA,testB,testC);
Run Code Online (Sandbox Code Playgroud)
显然,由于递归扩展,它只会声明void f1(); ,其余的不会扩展:
void f1(); FUNCTION_TABLE(f2,f3,testA,testB,testC);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我可以使用什么样的技巧来实现递归扩展?问题是我需要支持许多参数(最多100个),我绝对不能使用boost.
我正在使用委托从非托管代码调用托管代码.当我在默认的AppDomain中调用托管代码时,我每次调用的平均值为5.4ns.当我呼叫第二个AppDomain时,我每次呼叫的测量值为194ns.(默认VS2017 x86发布配置,不在调试器下运行).
调用不是默认的AppDomain时,为什么性能会低得多?由于我来自非托管方,它不了解AppDomains,我希望直接调用目标域.但是,性能打击意味着委托调用默认域然后编组到真实目标.我确实看到了UM2MDoADCallBack踩踏拆装的时候.它出现WrongAppDomain:在UMThunkStub.asm中
如何防止这种不必要的封送并直接调用特定的AppDomain?
我用来测试它的代码如下.
#pragma unmanaged
#include <wtypes.h>
#include <cstdint>
#include <cwchar>
typedef void (__stdcall *ManagedUpdatePtr)();
struct ProfileSample
{
static uint64_t frequency;
uint64_t startTick;
wchar_t* name;
int count;
ProfileSample(wchar_t* name_, int count_)
{
name = name_;
count = count_;
LARGE_INTEGER win32_startTick;
QueryPerformanceCounter(&win32_startTick);
startTick = win32_startTick.QuadPart;
}
~ProfileSample()
{
LARGE_INTEGER win32_endTick;
QueryPerformanceCounter(&win32_endTick);
uint64_t endTick = win32_endTick.QuadPart;
uint64_t deltaTicks = endTick - startTick;
double nanoseconds = (double) deltaTicks / (double) frequency * 1000000000.0 / count;
wchar_t …Run Code Online (Sandbox Code Playgroud) 我已经在stackoverflow和apple网站上阅读了很多线程,但我仍然无法使用基础知识.我做了我的应用程序的调试版本,我在手机上安装它,这个版本故意崩溃.我在没有连接Xcode调试器时运行这个应用程序.应用程序崩溃了,我如何看到崩溃回溯的功能名称和行号?
我试图在Xcode中打开设备窗口并在那里查看日志,我看到我的应用程序崩溃日志,我看到我的代码在崩溃之前有多个函数调用,但所有这些函数都显示为十六进制地址而不是实际符号化.我需要做些什么来使它工作?
我使用一个第三方项目,它会产生大量警告。我在 VS 项目属性中禁用了所有这些。有时,我会切换到LLVM clang-cl工具集来检查 clang 发出的警告。第 3 方项目使用 clang-cl 产生如此多的警告,以至于 VS 的输出量令人窒息。我知道如何禁用它们,我通过命令行参数来做到这一点,例如:Wno-int-conversion -Wno-shift-op-parentheses等。但是,问题是,当我切换回 VS 工具集时,所有这些禁用 clang-cl 警告的命令行参数都会变成错误(未知) cmd line args) 与 MS 编译器。
有没有办法在同一个 VS 项目中同时拥有 clang 和 VS 设置?也许,以某种方式以 ClangCL 工具集为条件,只能为 clang-cl 构建添加这些工具集?
我这样做:
FILE* f_cert = fopen("cert", "rb");
X509* x_cert = NULL;
PEM_read_X509(f_cert, &x_cert, NULL, NULL);
...
Run Code Online (Sandbox Code Playgroud)
现在我想自己读取"cert"文件,并使用PEM_read_bio_X509而不是PEM_read_X509.所以,如果我已经有这些变量:
const char cert_data[] = {....};
const int sert_data_size = 123;
Run Code Online (Sandbox Code Playgroud)
我如何初始化BIO,将其传递给PEM_read_bio_X509并释放临时生物?
我从事一个与解析器相关的项目,并使用递归下降解析器实现它。但问题是,它很容易导致堆栈溢出。处理此类问题的技术是什么?
为了便于说明,这里是简单的数学表达式解析器,支持加法、减法、乘法和除法。可以使用分组括号,它们显然会触发递归。
这是完整的代码:
#include <string>
#include <list>
#include <iostream>
using namespace std;
struct term_t;
typedef list<term_t> prod_t;
typedef list<prod_t> expr_t;
struct term_t
{
bool div;
double value;
expr_t expr;
};
double eval(const expr_t &expr);
double eval(const term_t &term)
{
return !term.expr.empty() ? eval(term.expr) : term.value;
}
double eval(const prod_t &terms)
{
double ret = 1;
for (const auto &term : terms)
{
double x = eval(term);
if (term.div)
ret /= x;
else
ret *= x;
}
return ret; …Run Code Online (Sandbox Code Playgroud) 假设我的本地分支上有以下版本历史记录:
A -- B -- C
Run Code Online (Sandbox Code Playgroud)
如何在 A 和 B 之间插入新版本 X,以便版本历史记录如下所示:
A -- X -- B -- C
Run Code Online (Sandbox Code Playgroud)
请注意,过去有一个关于如何插入提交的类似问题,但是,在我的情况下有点不同:X 引入的任何更改都不会传播到 B,在版本 X 插入 A 之间后,B 应该保持不变和B。
我有可以使用 masm(ml.exe 或 ml64.exe)为 x64 和 x86 组装的 asm 文件。masm 中是否有一些预定义的宏来检测正在为 x64 组装的文件?现在我手动定义了 _WIN64 然后对其进行测试,但必须有更好的方法来检查它。
有没有办法检查所有本机 jni 方法是否已正确绑定,而不是尝试调用它们并获取 java.lang.UnsatisfiedLinkError 异常。有时方法签名会在任何一方发生变化而没有正确更新 java 或 c++ 端,我想添加一些调试代码来检测这些问题并处理它们(也许通过生成正确的方法签名并将其打印到日志中,以便我可以轻松修复代码)。
我更喜欢 JNI 解决方案,但如果可以在 java 端的帮助下完成某些操作,那么也可以。如果我使用 registerNatives 并注册未在 java 中声明的方法,则会失败并将其打印到 logcat:
E/dalvikvm( 1445): ERROR: couldn't find native method
E/dalvikvm( 1445): Requested: Lcom/bla/bla/bla/Test;.nativeTestXX:()Z
Run Code Online (Sandbox Code Playgroud)
但我想捕获这个错误并自己处理。有可能做到吗?
编辑: 在我的 JNI 代码中,我有一个静态的 nativeInit (如Android JNI Tips中所建议的),它注册所有本机方法。在同一函数中,我想验证所有本机方法是否已正确绑定。也就是说,我不需要等到调用某些未初始化的方法并且应用程序存在。我遇到的问题是:有很多 jni 代码是由不同的人在不同的时间编写的,并且某些方法根本不正确,但它们仅在某些模糊的条件下使用。我认为对我来说最好的方法是检查所有本机方法是否都绑定到某个 C++ 函数。另一个问题是,部分 JNI 代码通过导出所有这些 Long_java_name 来使用绑定,其中任何一方的方法签名更改都无法检测到。