GCC는 AT & T 스타일 어셈블리에서 가장 잘 작동하며 GAS는 모든 Intel 구문을 구현하지 않습니다. 귀하의 즉각적인 문제는 숫자로 해석되지 않는 110b
에서 오는 것이지만 그 전부는 아닙니다.
GCC의 인라인 어셈블러 구문에서 직접 변수를 참조 할 수 없습니다. 당신은 (기본 -masm=att
사용)처럼 작성해야 :
int foobar(int num) {
int result;
asm("mov %1, %%eax\n\t"
"add $6, %%eax\n\t"
"sub $2, %%eax\n\t"
"mov %%eax, %0"
: "=g" (result)
: "g" (num)
: "eax", "cc");
return result;
}
를 첫 번째 콜론 출력 피연산자의 쉼표로 구분 된 목록이 후. "=g" (result)
이 첫 번째 제약이므로 result
은 별칭 %0
을 얻습니다. "=g"
은 GCC에 %0
이 범용 레지스터 또는 메모리가 될 수 있음을 나타냅니다. (=
대신에 대신에 GCC는 동일한 목적으로 여러 레지스터를 재사용하기로 결정할 수 있으므로 모든 방법이 사용되는 방식을 정확하게 알려야합니다.)
두 번째 콜론 뒤에는 쉼표로 구분 된 입력 피연산자 목록 "g" (num)
이 두 번째 제약 조건이므로 num
은 별칭 %1
을 얻습니다. "g"
은 읽기 전용임을 의미합니다.
세 번째 콜론 뒤에는 쉼표로 구분 된 clobbers 목록이 있습니다. 이것은 GCC가 인라인 어셈블리를 통해 유지하고있는 정보를 다시로드해야하므로 인라인 어셈블리가 이러한 레지스터/메모리를 입력 또는 출력하지 않아도 변경할 수 있음을 GCC에 알려줍니다. 여기서 우리는 분명히 %eax
을 변경하고 조건 코드 (플래그) 레지스터는 add/sub
의 영향을받습니다. 컴파일러가 생성 조립체에
룩은 :
$ cc -S -o- -m32 asmtest.c | sed -n /globl.foobar/,/-foobar/p
.globl foobar
.type foobar, @function
foobar:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
#APP
# 15 "asmtest.c" 1
mov 8(%ebp), %eax
add $6, %eax
sub $2, %eax
mov %eax, -4(%ebp)
# 0 "" 2
#NO_APP
movl -4(%ebp), %eax
leave
ret
.size foobar, .-foobar
컴파일러는 직접 num
및 result
의 적층 위치를 사용하기로 결정 하였다. :"=g":"g"
(레지스터 또는 메모리 위치를 허용) 대신 :"=r":"r"
제약 조건 (레지스터 만 허용 함)을 사용하면 컴파일러는 인라인 어셈블리 전후에 레지스터간에/레지스터를 복사합니다. 당신이 정말로, 인텔 구문을 사용하여 별도의 .s
소스 파일에 넣어 NASM 독립적를 조립하려면
$ cc -S -o- -m32 asmtest.c | sed -n /globl.foobar/,/-foobar/p
.globl foobar
.type foobar, @function
foobar:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl 8(%ebp), %edx
#APP
# 15 "asmtest.c" 1
mov %edx, %eax
add $6, %eax
sub $2, %eax
mov %eax, %edx
# 0 "" 2
#NO_APP
movl %edx, -4(%ebp)
movl -4(%ebp), %eax
leave
ret
.size foobar, .-foobar
후 함께 개체를 연결합니다.
$ cat asmtest.c
#include <stdio.h>
int foobar(int);
/* int foobar(int) __attribute__((fastcall)); */
int main() {
int n = 0;
printf("Number: ");
scanf("%d", &n);
printf("%d\n", foobar(n));
return 0;
}
$ cat foobar.s
global foobar
foobar:
mov eax,[esp+4] # take this line out if C prototype is marked fastcall
sub eax,110b
add eax,2
ret
$ nasm -f elf foobar.s
$ cc -m32 asmtest.c foobar.o
$ ./a.out
Number: 30
26
(-f elf
Windows 용 정확하지 않지만. 어쩌면 -f win32
? 그리고 때문에 윈도우의 어리 석음에, 당신은 어셈블리의 이름 _foobar
을 사용 할 수 있습니다.)
알 수없는 경우 어떻게 이전 버전인지 어떻게 알 수 있습니까? – bmargulies