我的MASM上有点生疏,所以我真的不记得在这里做什么(如果有什么需要做的话).我有一个MASM(X86)例程,如下所示.它有两个局部变量,共占用5个字节:
MSC_ASM_GenerateBlock PROC buffer:DWORD,bsize:DWORD,safety:DWORD
LOCAL val:DWORD, rc:BYTE ;; local variables
MWSIZE EQU 4 ;; machine word size
.WHILE bsize >= MWSIZE && safety > 0
;; RDRAND is not available prior to VS2012. Just emit
;; the byte codes using DB. This is `rdrand eax`.
DB 0Fh, 0C7h, 0F0h
setc rc
...
.ENDW
...
MSC_ASM_GenerateBlock ENDP
Run Code Online (Sandbox Code Playgroud)
当我检查拆卸时,我看到:
> dumpbin.exe /DISASM rdrand-x86.obj
Dump of file rdrand-x86.obj
_MSC_ASM_GenerateBlock:
00000000: 55 push ebp
00000001: 8B EC mov ebp,esp
00000003: 83 C4 F8 add …Run Code Online (Sandbox Code Playgroud) 我正在调试英飞凌Tricore TC275上的加密实现代码(参考汇编语言).
PMI_PSPR (wx!p): org = 0xC0000000, len = 24K /*Scratch-Pad RAM (PSPR)*/
DMI_DSPR (w!xp): org = 0xD0000000, len = 112K /*Local Data RAM (DSPR)*/
Run Code Online (Sandbox Code Playgroud)
在调用mac函数后,堆栈指针a [10]始终指向保留的存储区域.
###### typedefs ######
typedef uint16_t limb_t;
typedef limb_t gf_t[DIGITS]; //DIGITS=312
typedef int32_t dslimb_t;
################################
/**Multiply and accumulate c += a*b*/
void mac(gf_t c, const gf_t a, const gf_t b)
1: 0xC0000812: D9 AA 40 9F LEA a10,[a10]-0x9C0 //Load eff. addr.
/*Reference non-Karatsuba MAC */
dslimb_t accum[2*DIGITS] = {0};
2: …Run Code Online (Sandbox Code Playgroud) 对于上下文,这是从引导加载程序调用的代码,该引导加载程序应引导到主应用程序中。该代码段来自带有参数的函数,该参数uintptr_t address指定了写入主应用程序的地址。我相信sp和pc分别是堆栈指针和程序计数器。
这是代码:
sp = *((void **)address + 0);
pc = *((void **)address + 1);
start_new_application(sp, pc);
Run Code Online (Sandbox Code Playgroud)
这里的完整上下文
然后我走了,打印了地址,sp和pc,发现了以下内容:
address -> 0x08010000
sp ------> 0x20050000
pc ------> 0x080132DD
Run Code Online (Sandbox Code Playgroud)
这让我很困惑。我不确定为什么该sp行中有一个+ 0。该sp行可以改写为:
sp = (void *)address;
Run Code Online (Sandbox Code Playgroud)
并做同样的事情?
我的理解是,该地址已被static_casted为一个double void指针,然后sp被赋予地址的解除引用值(0x08010000),并pc已被赋予地址的解除引用值(0x08010001)。然后,在我的printf语句中,显示的这些值是这些地址的取消引用的值。
我的理解在这里正确吗?
SS、SP、BP的初始值是多少?它们是否为空 (0x0) 或者例如 SP 是否立即设置为 0xFFFE?
当我们编写汇编代码而不使用 pop 和 push 语句时,堆栈指针是否设置为一个值?
为什么这段代码不打印"测试"?
#include <stdio.h>
#include <stdlib.h>
void foo ( void ) {
printf("test\n");
}
__declspec(naked)
void bar ( void ) {
asm {
push 0x000FFFFF
call malloc
pop ecx
push eax
add eax, 0x000EFFFF
mov ecx, esp
mov esp, eax
push ecx
call foo
pop esp
call free
pop ecx
ret
}
}
int main(int argc, char* argv[])
{
bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我正在检查 C 代码,其中我必须计算出特定程序跟踪中使用的寄存器数量。每当遇到推送或弹出命令时,代码都会忽略存储 ESP 寄存器。我还引用了 X86 指令,它那里写着“ESP,堆栈指针,不应该使用”。为什么?
众所周知,微处理器执行任务的过程只是从存储器一个接一个地执行二进制指令,并且有一个程序计数器保存下一条指令的地址。因此,如果我没有记错的话,这就是处理器执行任务的方式。但是还有另一个名为堆栈指针的指针,它的作用与程序计数器几乎相同。我的问题是为什么我们需要一个堆栈指针来指向内存(堆栈)的地址?有人可以告诉我堆栈指针和程序计数器之间的主要区别吗?
我一直在阅读 ARM 信息中心的各个部分以尝试找到我的答案,但是我发现文档让我感到困惑,所以我希望这里有人可以提供帮助。
我知道 Cortex-M 处理器中有两个堆栈:
我试图弄清楚 ARM 内核如何使用每一个。
ARM 信息中心中讨论 Cortex-M3 时的文档说明如下:
主堆栈在复位时使用,并且始终在处理程序模式下使用(进入异常处理程序时)。进程堆栈指针仅在线程模式下可用作当前堆栈指针。
好的,这告诉我 MSP 在重置时使用。但是,文档还说明了以下内容:
用于执行应用软件。处理器退出复位后进入线程模式。
用于处理异常。处理器在完成所有异常处理后返回线程模式。
好吧,这就是让我困惑的地方。如果在复位时使用MSP,并且总是在Handler模式下使用,而PSP在线程模式下使用,那么如果处理器在复位时处于线程模式,如何在复位时使用MSP?
我正在编写一个非常优化的叶子函数,为了使其运行更快,我想使用R13作为通用寄存器。在使用R13并将其从功能返回之前,我通过将R13移至VFP寄存器之一来保留它,方法是将其移回。看起来像这样:
/* Start of the function */
push { r4 - r12, r14 }
vmov s0, r13
/* Body of the function. Here I use R13
* as a general purpose register */
vmov r13, s0
pop { r4 - r12, r14 }
bx lr
Run Code Online (Sandbox Code Playgroud)
而且有效。但是我已经读到某些操作系统假定R13始终用作堆栈指针,并将其用作通用寄存器可能会导致崩溃。我还应该说这个功能只能在Android(Linux)上运行。谢谢!
使用汇编代码,想知道为什么我的subl $ 8,%esp指令出现段错误?
pushl %ebp
movl %esp, %ebp
movl 16(%ebp), %esi
movl 12(%ebp), %edi
movl 8(%ebp), %eax
movl $0, %ebx
subl $8, %esp
jmp .LL1
.LL1:
cmpl %ebx, %esi
je .LL2
movl %ebx, 4(%esp)
movl %eax, (%esp)
addl $1, %ebx
jmp .LL1
.LL2:
popl %ebp
ret
Run Code Online (Sandbox Code Playgroud)
在subl $ 8上出现segfault,%esp