저는 어셈블리 프로그래밍에 익숙하지 않습니다. 저는 GCC (Linux)에서 x86 플랫폼을 사용하고 있습니다.어셈블리 함수에 대한 포인터 전달
이 나는대로 C에서 호출하고자하는 기능을 가지고 :
myfunc (unsigned char * s1, unsigned char * s2, int someint);
일부 처리를하고, 등, 증가와 비교 후, S1과 S2의 메모리 위치를 가지고 그들을 비교합니다 기능 그것은 간다. 이것은 memcmp와 비슷하지만 더 많이하고 있습니다.
내 질문 : 포인터를 어셈블리 함수에 전달하면 어떻게됩니까? 그런 다음 "이 메모리 주소에 저장된 값을 알려주십시오"라고 어떻게 말합니까? 여기
는 지금까지이 작업은 다음과 같습니다가 스택에서 첫 번째 함수의 인수 ("S1")을 얻으려면, 내가 someaddress 32 비트 정수 (이렇게, 나는 32에서 일하고 있어요 비트 프로세서) I 등 %eax
(또는 %ebx
로 somevar
넣으면
movl 8(%esp), %ecx
movl %ecx, someaddress
) 다음은의 printf를 %p
와, I는 주소 및 서명 숯불 포인터의 주소가 "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;
}
총회 프로그램 : cmp
에 피연산자의
.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
업데이트 된 코드 문제 : 값을 인쇄하려면 변수가 단지 8 비트 인 반면 32 비트를 푸시해야합니다. 32 비트 (C가하는 것)로 확장하거나 형식 문자열을 변경할 수 있습니다. -1543299247의 하위 8 비트는 실제로 예상대로 81로 평가됩니다. 두 번째 인쇄 및 반환 : 쓰기 (str)로 이중 참조를 사용하려고 시도 했으므로 x86에는 그런 것이 없습니다. 당신이 나에게 묻는다면 어셈블러는 에러를 던져야하지만 대신에 괄호를 조용히 버린다. – Jester