当我运行以下代码时,
int x[4096];
int *y;
int *m;
void main()
{
y = (int*)malloc( 4096 * sizeof(int) );
m = (int*)mmap( 0, 4096 * sizeof(int), PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 );
printf( "x = %p, y = %p, m = %p\n\n", x, y, m );
system( "cat /proc/self/maps" );
}
Run Code Online (Sandbox Code Playgroud)
我得到以下输出,
x = 0x601060, y = 0x606010, m = 0x7ffff7ff5000
00400000-0040b000 r-xp 00000000 08:01 655382 /bin/cat
0060a000-0060b000 r--p 0000a000 08:01 655382 /bin/cat
0060b000-0060c000 rw-p 0000b000 08:01 655382 /bin/cat …Run Code Online (Sandbox Code Playgroud) 我发现了以下汇编代码,我不知道它应该做什么(主要是因为cmovg遵循movl指令):
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl %edx, %eax
sarl $31, %eax
testl %edx, %edx
movl $1, %edx
cmovg %edx, %eax
popl %ebp
ret
Run Code Online (Sandbox Code Playgroud)
所以这就是我到目前为止解释它的方式:推进堆栈
新指针(堆栈指针)创建指向与基指针相同的位置
获取输入(让我们称之为x)
将x复制到寄存器%eax(res = x)
res = res >> 31符号扩展名
测试x
设置x = 1
if>,res = x
恢复指针
返回res
但是,我不确定这个子程序的意义是什么.对我来说似乎毫无用处.如果你能指出这里做了什么,我将不胜感激.
为了我自己的病态,我正在编写一个用于Linux的x86_64程序集中的小程序.但是,在一个比较立即操作数和寄存器的指令中,我遇到了一个对我来说完全没有意义的段错误.是什么赋予了?
这是导致崩溃的代码:
_start:
sub $8, %rsp
mov %rsp, %rbx
lea le_string(%rip), %rsi
mov %rsi, %rdi
add $8, %rdi
mov $26, %cl
mov (%rsi), %al
cmp 'A', %al /* This line segfaults */
/* snip code that never runs */
le_string:
.ascii "YrFgevat"
Run Code Online (Sandbox Code Playgroud)
我正在组装gcc -nostdlib,它正在调用GNU汇编程序.
崩溃后倾倒寄存器显示:
%rsi 包含指向字符串的预期指针%al 包含字符串中预期的第一个字符%rip 指向不接触内存的指令请忽略缺少正常的调用约定 - 除了系统调用接口之外我没有调用任何东西,并且在它甚至到达那么远之前崩溃了!
我一直试图尝试英特尔调试寄存器,但我似乎做错了什么.我创建了一个非常简单的Linux LKM,并尝试使用内联汇编来执行寄存器的简单操作.例如:
__asm__ ("movl %eax, %db0");
Run Code Online (Sandbox Code Playgroud)
我得到的错误消息表明我做的事情从根本上是错误的.例如:
Error: unsupported for `mov'
Run Code Online (Sandbox Code Playgroud)
有没有人对如何使用这些寄存器有任何见解?
所以,我有3个参数的汇编程序ASM_Method(void*, void*, int)和init_method(float, int*).感兴趣的是前者的无效指针.
当我从C++文件中调用方法时,参数为:
float src[64];
float dest[64];
int radius[3];
init_method(1.5, radius);
ASM_Method(src, dest, 64);
Run Code Online (Sandbox Code Playgroud)
反汇编这个调用过程:
mov r8d,100h
lea rdx,[rbp+0A0h]
lea rcx,[rbp-60h]
call ASM_Method
Run Code Online (Sandbox Code Playgroud)
是否已初始化,程序运行正常.但是,当我这样做时:
float* src = new float[64];
float* dest = new float[64];
int radius[3];
init_method(1.5, radius);
ASM_Method(src, dest, 64);
Run Code Online (Sandbox Code Playgroud)
调用时,RCX设置为非正确地址的值,但RDX是正确的.程序崩溃了.
反汇编这个调用过程:
mov r8d,100h
mov rdx,rbx
mov rcx,rdi
call ASM_Method
Run Code Online (Sandbox Code Playgroud)
除非我将src初始化为某些值,否则RCX在调用时会更改为无效地址(在本例中为1).
ASM_Method的汇编代码:
mov rax, rdx
add rax, r8
shr r8, 4
inc r8
xor r9, r9
movdqu xmm1, [rax]
MainLoop:
movdqu xmm0, [rcx …Run Code Online (Sandbox Code Playgroud) 在x86-32汇编中,参数存储在堆栈中,但在x86-64中,参数存储在寄存器中.这是什么原因?
Intel的存储器保护扩展提供了四个新的128位界定寄存器,BND0向BND3每个存储对64位下界(LB)和上界(UB)的缓冲液中的值.
如何提取下界的64位值(即%BND0[0-63]进入64位通用寄存器(即%RAX))?
据我所知,问题在于英特尔的指令集没有提供直接执行此操作的方法.我已经查阅了英特尔的MPX支持指南(参见本链接底部的下载),发现有一条BNDMOV b/m, b指令可以将边界寄存器中的下界和上界存储到存储器或其他寄存器中.但是看起来另一个寄存器必须是一个边界寄存器本身,因为它不可能将128位边界寄存器装入64位通用寄存器.
另外,据我所知,通过使用半宽同级寄存器(即%EAX包含下半部分的值),无法从边界寄存器中获得下限%RAX.同样,没有寻址%BND#.LB,即使无花果.14 on pg." MPX启用指南"中的50个显示了一个监视这些值的调试器.
我正在寻找一个执行以下操作的程序:
./prog &pmap工具,程序和[stack]字段.这个问题不仅仅是学术性的,我正在研究内存扫描仪,我需要一个最小的例子来处理.
我能想出的最小(纯C)是:
#include <unistd.h>
int main(int argc, char **argv)
{
pause();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是我确信这可以与一些程序集/编译器/ C奥术魔法相形见绌,因为这个程序+堆栈超过180 KB.
SHA1MSG1是Intel指令,用于计算用于计算SHA1哈希值的步骤。我使用它的方式如下(采用AT&T语法):
sha1msg1 %xmm14, %xmm13
Run Code Online (Sandbox Code Playgroud)
我可以编译我的代码。当我运行我的代码时,它给出一个错误:
Illegal instruction (core dumped)
Run Code Online (Sandbox Code Playgroud)
我使用调试了代码ida pro,但此指令出现错误,如下所示:
401839: got SIGILL signal (Illegal instruction) (exc.code 4, tid 48292)
Run Code Online (Sandbox Code Playgroud)
我试图找到该指令的示例用法,但没有找到任何用法。我想我根据规格正确使用了它。知道我做错了什么吗?
顺便说一句,我正在使用Ubuntu 64位。
我在x86-64汇编中开发了一个程序,该程序需要通过相同的操作进行多次迭代:
IMUL rdx, 3 # rdx is always different
Run Code Online (Sandbox Code Playgroud)
但是,我需要使运行时更快,因此我从上面想到了对该特定行的优化:
MOV rcx, rdx
SHL rdx, 1
ADD rdx, rcx
Run Code Online (Sandbox Code Playgroud)
现在我问你们:这种修改会改善程序的运行时间(减少时钟),还是我应该坚持使用该IMUL命令?