我有以下几条线,我不明白。希望有人可以帮助我:
.....
MOV EAX, DWORD PTR SS:[EBP-0x4]
SHL EAX, 0x2
ADD EAX, DWORD PTR SS:[EBP-0x8]
PUSH EAX
....
通常,它可以帮助我将其翻译成C语言。但不知何故,我无法找到办法在这种情况下做到这一点。 所以,我只知道在SHL的第二行,寄存器乘以4。 并且DWORD PTR SS:[EBP-0x4]看起来像一个数组表示,但我不确定。
我还找到以下链接
x86 Assembler: shl and other instructions
但我不明白那里的答案。 所以我的问题是:那里发生了什么?谢谢......
答案 0 :(得分:1)
[EBP-0x4]表示访问地址[EBP-0x4]的内存内容,EBP是基址寄存器,例如,如果EBP中的值为16,那么您将从地址处的内存中读取值[16-4]即。在地址12.(我使用简单的数字,这些地址将导致访问冲突)。这就像在C / C ++中取消引用指针一样。 SS:前缀,只是说地址是相对于堆栈段的。 DWORD PTR修饰符告诉汇编器生成将从内存移动到EAX的4个字节的操作码。
其余的解释在代码中作为注释。
; Load the 4 byte (DWORD) value from address EBP-0x4 relative to the stack segment
; into the EAX register
MOV EAX, DWORD PTR SS:[EBP-0x4]
; Shift the value in the EAX register left 2 bits. In pseudo C EAX <<= 2
SHL EAX, 0x2
; Add the DWORD value at address (value in EBP register)-0x8
; to the value in EAX and store the result in EAX
ADD EAX, DWORD PTR SS:[EBP-0x8]
; Push the value of EAX onto the stack
PUSH EAX
看到[EBP-xxx]是很常见的原因是这是你如何访问在堆栈上传递给函数的参数。例如,调用者将参数推送到堆栈然后调用函数,函数将设置堆栈帧,以便参数相对于EBP。然后可以相对于EBP完成访问参数。
我对代码的阅读将是这样的(假设在X86上调用cdecl约定) 请注意下面的警告。
int Func(int x,int y) { 返回x * 4 + y; }
有一点需要注意,最后的推送eax没有被表示,如果这是所有代码,它实际上会使堆栈失去平衡,但我认为有比此更多的代码或者是从决定的代码中提取的代码结果将留在堆栈而不是在EAX中,这是cdecl调用约定的方式。
阅读调用约定和堆栈帧以更好地理解这一点。 http://en.wikipedia.org/wiki/X86_calling_conventions
我希望这可以帮助你开始。
答案 1 :(得分:0)
a = 00001 = 1
shift 1 bit to the left
a = 00010 = 2
shift 1 bit to the left
a = 00100 = 4
each time you shift to the left you multiply
another example:
a = 00011 = 3
shift to the left 1 bit
a = 00110 = 6
as you can see shifting to the left multiply by 2
SHL EAX, 0x2 ;multiply by 4 because it shifts 2 bits to the left.