上个学期我在信息学的计算机体系结构考试中得到了这个问题:
"为什么MASM中的'DIV EDX'总是会产生处理器异常?"
产生异常的机制是什么?
对不起,如果这里有人问过并回答过,那么简单的搜索并没有给我太多帮助.随意更正标签,并提供以下问题的链接或主题的讨论.另外,我在某种程度上了解Windows,而不是Linux,因此这些问题可能显得微不足道.
一些Windows应用程序使用注册表和其他一些不起眼的地方来存储他们的激活数据,试用期还剩下几天,只是软件已经安装在这个操作系统上.
Linux中有类似的地方吗?
如果有,那么数据是多么容易被发现,因为你不仅拥有root访问权限,而且几乎所有的源代码都可以调整内核并强制获取内容?
如果没有办法在Linux中保护这些数据,所有其他条件相同,它对Linux商业软件的可用性有多大影响?
我有为多个CPU编写的性能关键代码.我在运行时检测CPU,并根据检测到的CPU使用适当的函数.所以,现在我必须使用函数指针并使用这些函数指针调用函数:
void do_something_neon(void);
void do_something_armv6(void);
void (*do_something)(void);
if(cpu == NEON) {
do_something = do_something_neon;
}else{
do_something = do_something_armv6;
}
//Use function pointer:
do_something();
...
Run Code Online (Sandbox Code Playgroud)
这并不重要,但我会提到我已经针对不同的cpu优化了功能:armv6和armv7以及NEON支持.问题是通过在许多地方使用函数指针,代码变得更慢,我想避免这个问题.
基本上,在加载时,链接器使用函数地址解析relocs和patch代码.有没有办法更好地控制这种行为?
就个人而言,我提出了两种避免函数指针的方法:为cpu依赖函数创建两个独立的.so(或.dll),将它们放在不同的文件夹中,并根据检测到的CPU将这些文件夹中的一个添加到搜索路径中(或者LD_LIB_PATH).加载主代码和动态链接器将从搜索路径中获取所需的dll.另一种方法是编译两个独立的库副本:)第一种方法的缺点是它迫使我至少有3个共享对象(dll):两个用于cpu依赖函数,一个用于使用它们的主代码.我需要3,因为在加载使用这些cpu相关函数的代码之前,我必须能够进行CPU检测.关于第一种方法的好处是应用程序不需要为多个CPU加载相同代码的多个副本,它将仅加载将使用的副本.第二种方法的缺点是非常明显的,不需要谈论它.
我想知道是否有办法在不使用共享对象的情况下执行此操作并在运行时手动加载它们.其中一种方法是涉及在运行时修补代码的一些hackery,它可能太复杂而无法正确完成它).有没有更好的方法来控制加载时的重定位?也许将cpu依赖函数放在不同的部分,然后以某种方式指定哪个部分具有优先级?我认为MAC的男子气概有类似的东西.
ELF-only(针对手臂目标)解决方案对我来说已经足够了,我并不真正关心PE(dll's).
谢谢
我想在程序集中获取函数的返回地址,然后将该返回地址值与另一个值进行比较,而不会破坏堆栈或更改堆栈中的任何内容,
怎么能在集会中完成?
我正在使用x86
我刚刚读完这在ISO 9660文件系统读取文件的文章,我对我怎么会去读取文件到内存困惑.我知道根目录位于PVD的偏移量156处,如何使用它来查找驻留在根目录中的文件,一旦找到文件名,我将如何找到该文件所在的地址,这样我就可以将它加载到内存中(使用int 0x13 AH = 42)?
我对傅里叶变换的有限理解是,您应该能够在时域和频域之间切换,而无需更改原始数据.所以,这里是我(我想)我在做什么的总结:
使用kiss_fft_next_fast_size(994)以确定我应该使用1000.
使用kiss_fft_alloc(...)创建kiss_fft_cfg用nfft = 1000.
通过将额外点填充为零,将输入数据从大小994扩展到1000.
将kiss_fft_cfg传递给kiss_fft(...)我的输入和输出数组.
使用kiss_fft_alloc(...)创建逆kiss_fft_cfg用nfft = 1000.
传递逆kiss_fft_cfg以kiss_fft(...)输入先前的输出数组.
期待原始数据回来,但每个数据准确地大1000倍!
我在这里放了一个完整的例子,最后可以找到我的50多行代码.虽然我可以通过将每个结果除以OPTIMAL_SIZE(即1000)的值来解决这个问题,但是如果没有理解为什么那么修复会使我感到非常不安.
请问你能说出我做错的愚蠢事吗?
我从编译器行为的角度发现了奇怪,它允许赋值布尔值* char.
char * k= false;
Run Code Online (Sandbox Code Playgroud)
为什么?但是在赋值后,char仍未初始化.为什么编译器不允许赋值int?
我正在使用NASM编写我的第一个OS引导扇区.我有它的工作,它只显示"Hello OS world!" 用红色字母.很简单.我已将boot.asm转换为boot.bin,并将其转换为boot.img.我正在使用VMWare播放器,我将boot.img作为软盘驱动器安装并从那里启动它工作得很好.但是这个汇编代码有几行是我不明白的目的.
org 07c00h
mov ax, cs
mov ds, ax
mov es, ax
call DispStr
jmp $
DispStr:
mov ax, BootMessage
mov bp, ax
mov cx, 16
mov ax, 01301h ;
mov bx, 000ch ;
mov dl, 0 ;
int 10h ;
ret
BootMessage: db "Hello, OS world!"
times 510-($-$$) db 0
dw 0xaa55 ;
Run Code Online (Sandbox Code Playgroud)
以分号结尾的行是我不理解的行.我做了很多谷歌搜索,并能够弄清楚其他的东西.我很擅长写作大会.因此,例如,我知道mov ax,01301h移动01301h到AX寄存器.但我不明白为什么,或者有多01301h重要.我猜他们有点像格式化字符串的参数,但这只是猜测.任何和所有的帮助将不胜感激.
我在C中实现了一个使用浮点数的算法.当我在i386上编译并运行时,我得到的结果与我在armel上编译和运行时获得的结果不同.特别是按浮点数划分,会产生不同的浮点数.
我从算法中提取了一些代码来演示这个问题:
#include <stdio.h>
void main(void)
{
float x = 4.80000019;
float y = 4.80000019;
int a = 38000;
int b = 10000;
int result = (a/x)+(b/y);
printf("%.8f, %.8f\n", x, y); // same on i386 and armel
printf("%f, %f\n", a/x, b/y); // slightly different on each
printf("%d\n", result); // prints 9999 on i386, and 10000 on armel
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释为什么这两个平台产生不同的结果?
亚历克斯
在XC888微控制器上编程,我想为外部存储器中的某些数据保存缓冲区xdata.
我这样做(只是一个例子,我摆脱了不必要的代码):
Header.h
extern ubyte xdata rec_buffer[32];
Run Code Online (Sandbox Code Playgroud)
Function.c
ubyte xdata rec_buffer[32] = {0};
void foo()
{
//Option 1
rec_buffer[0] = 0xFF; // Doesn't work
//Option 2
ubyte xdata *ptr_buf = rec_buffer;
ptr_buf[0] = 0xFF // Doesn't work
}
Run Code Online (Sandbox Code Playgroud)
所以我无法弄清楚我在这里缺少什么.在这两种情况下,都没有数据写入缓冲区.(使用调试器检查).我还检查了指针指向它的地址 - >它实际上指向外部存储器(地址0x000000,但应该没有任何问题).
当我这样做而没有定义缓冲区时,xdata它的工作完全正常.我究竟做错了什么?有什么特别的方法我必须写入xdata吗?