Я новичок в программировании на ассемблере. Я использую платформу x86 с GCC (Linux).
У меня есть функция, которую я хочу вызвать из 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
, я вижу, что его адрес и адрес беззнакового указателя char « s1
», который я передал, совпадают. Но я подозреваю, что на самом деле я взял адрес памяти, преобразовал его в целое число, а затем поместил это целое число в некоторый адрес.
Например, если я сделаю это:
movl pos1, %eax
movl pos2, %ebx
cmp (%eax),(%ebx)
Я получаю сообщение «Ошибка: слишком много ссылок на память для `cmp '". Я' m не совсем уверен, что это означает, кроме "вы облажались"; -)
Итак ...
* ptr
в C) Хочу ли я взглянуть на операнд LEA?
Я использую «Программирование профессиональной сборки» Ричарда Блюма в качестве руководства, но Блюм этого не делает. Кажется, это дело не касается.
Обновление
Большое спасибо за ваш научный ответ!
К сожалению, я все еще не могу разыменовать.
Вот упрощенный пример. Функция сборки принимает указатель и должна повторить его. Вместо этого я получаю:
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