【发布时间】:2011-07-08 11:27:07
【问题描述】:
我对汇编编程比较陌生。我正在使用带有 GCC (Linux) 的 x86 平台。
我有一个我想从 C 调用的函数:
myfunc ( unsigned char * s1, unsigned char * s2, int someint );
该函数将获取 s1 和 s2 内存位置并比较它们,然后递增和比较等,同时进行一些处理。这有点像 memcmp,但我做得更多。
我的问题:如果我将指针传递给汇编函数? 那我怎么说“把存储在这个内存地址的值给我”呢?
这是我目前所拥有的:
为了从堆栈中取出第一个函数 arg(“s1”),我这样做(someaddress 是一个 32 位整数,我正在使用 32 位处理器):
movl 8(%esp), %ecx
movl %ecx, someaddress
如果我将somevar 放入%eax(或%ebx 等)然后用%p 打印它,我看到它的地址和无符号字符指针“s1”的地址我通过它是一样的。但我怀疑我实际上所做的是获取内存地址,将其转换为整数,然后将该整数放入 someaddress 中。
例如,如果我这样做:
movl pos1, %eax
movl pos2, %ebx
cmp (%eax),(%ebx)
我得到“错误:`cmp' 的内存引用过多”。我不完全确定这意味着什么,除了“你搞砸了”;-)
所以...
- 如何将指针传入并保持为指针?
- 如何在汇编中使用该指针的值? (例如,像 C 中的
*ptr)
我想查看 LEA 操作数吗?
我使用 Richard Blum 的“Professional Assembly Programming”作为我的指南,但 Blum 似乎没有涵盖这种情况。
更新
非常感谢您的学习回复!
很遗憾,我仍然无法取消引用。
这是一个简化的例子。汇编函数接受一个指针并且应该回显它。相反,我得到:
first_ptr points to 81 (should be 81) <-- from C program
the value is -1543299247 <-- printf called from within assembler
the value is -6028513 <-- printf called from within assembler
my function returned -6028513 <-- return value printed from C program
C 程序:
#include <stdio.h>
#include <string.h>
int main (void) {
unsigned char first;
unsigned char * first_ptr;
first = 'Q';
first_ptr = &first;
printf ("first_ptr points to %i (should be 81)\n",*first_ptr);
printf ("my function returned %i\n", myfunc(first_ptr));
return 0;
}
组装程序:
.section .data
msg:
.asciz "the value is %i\n"
.section .bss
.lcomm str, 8
.section .text
.type myfunc, @function
.globl myfunc
myfunc:
# save stack
pushl %ebp
movl %esp, %ebp
# save string arg from stack to "str"
movl 8(%esp), %ecx
movl %ecx, str
# let's try printing the ecx dereference
pushl (%ecx)
pushl $msg
call printf
# put the value of str on the stack
# and call printf
pushl (str)
pushl $msg
call printf
# now return the character at pos1
movl (str), %eax
# restore the stack
movl %ebp, %esp
popl %ebp
ret
【问题讨论】:
-
更新代码的问题:为了打印值,您推送 32 位,而变量只有 8 位。您可以将其扩展到 32 位(这是 C 所做的)或更改格式字符串。请注意,-1543299247 的低 8 位实际上确实计算为 81,正如预期的那样。对于第二次打印和返回:您正在尝试通过编写 (str) 来使用双重取消引用,而 x86 中没有这样的事情。如果你问我,汇编器应该为此抛出一个错误,但它会默默地删除括号。