所以我有一个简单的 C 程序,它循环传递给 main 的参数然后返回:
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for(i = 0; i < argc; ++i) {
fprintf(stdout, "%s\n", argv[i]);
}
return 0;
}
我想看看 gcc 如何以 NASM 格式写出程序集。我正在查看 .asm 文件中的输出,注意到语法是 TASM。下面是 make 文件和 gcc 的输出。我做错了什么还是 gcc 没有输出真正的 NASM 语法?
all: main
main: main.o
ld -o main main.o
main.o : main.c
gcc -S -masm=intel -o main.asm main.c
nasm -f elf -g -F stabs main.asm -l main.lst
AND
.file "main.c"
.intel_syntax noprefix
.section .rodata
.LC0:
.string "%s\n"
.text
.globl main
.type main, @function
main:
push ebp
mov ebp, esp
and esp, -16
sub esp, 32
mov DWORD PTR [esp+28], 0
jmp .L2
.L3:
mov eax, DWORD PTR [esp+28]
sal eax, 2
add eax, DWORD PTR [ebp+12]
mov ecx, DWORD PTR [eax]
mov edx, OFFSET FLAT:.LC0
mov eax, DWORD PTR stdout
mov DWORD PTR [esp+8], ecx
mov DWORD PTR [esp+4], edx
mov DWORD PTR [esp], eax
call fprintf
add DWORD PTR [esp+28], 1
.L2:
mov eax, DWORD PTR [esp+28]
cmp eax, DWORD PTR [ebp+8]
jl .L3
mov eax, 0
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.5.1 20100924 (Red Hat 4.5.1-4)"
.section .note.GNU-stack,"",@progbits
命令行上的错误是:
[mehoggan@fedora sandbox-print_args]$ make
gcc -S -masm=intel -o main.asm main.c
nasm -f elf -g -F stabs main.asm -l main.lst
main.asm:1: error: attempt to define a local label before any non-local labels
main.asm:1: error: parser: instruction expected
main.asm:2: error: attempt to define a local label before any non-local labels
main.asm:2: error: parser: instruction expected
main.asm:3: error: attempt to define a local label before any non-local labels
main.asm:3: error: parser: instruction expected
main.asm:4: error: attempt to define a local label before any non-local labels
main.asm:5: error: attempt to define a local label before any non-local labels
main.asm:5: error: parser: instruction expected
main.asm:6: error: attempt to define a local label before any non-local labels
main.asm:7: error: attempt to define a local label before any non-local labels
main.asm:7: error: parser: instruction expected
main.asm:8: error: attempt to define a local label before any non-local labels
main.asm:8: error: parser: instruction expected
main.asm:14: error: comma, colon or end of line expected
main.asm:17: error: comma, colon or end of line expected
main.asm:19: error: comma, colon or end of line expected
main.asm:20: error: comma, colon or end of line expected
main.asm:21: error: comma, colon or end of line expected
main.asm:22: error: comma, colon or end of line expected
main.asm:23: error: comma, colon or end of line expected
main.asm:24: error: comma, colon or end of line expected
main.asm:25: error: comma, colon or end of line expected
main.asm:27: error: comma, colon or end of line expected
main.asm:29: error: comma, colon or end of line expected
main.asm:30: error: comma, colon or end of line expected
main.asm:35: error: parser: instruction expected
main.asm:36: error: parser: instruction expected
main.asm:37: error: parser: instruction expected
make: *** [main.o] Error 1
是什么让我相信这是 TASM 语法是在此链接上发布的信息:http://rs1.szif.hu/~tomcat/win32/intro.txt
TASM 编码员通常对 NASM 存在词汇困难,因为它
缺少 TASM 中广泛使用的“ptr”关键字。
TASM 使用这个:
mov al,字节 ptr [ds:si] 或 mov ax,字 ptr [ds:si] 或 mov eax,
双字指针 [ds:si]
对于 NASM,这简单地翻译为:
mov al, byte [ds:si] 或 mov ax, word [ds:si] 或 mov eax, dword
[DS:SI]
NASM 在许多地方允许使用这些尺寸关键字,从而为您提供
以统一的方式对生成的操作码进行大量控制,例如
示例 这些都是有效的:
推双字 123 jmp [ds: 字 1234] ;这些都指定了尺寸
偏移量 jmp [ds: dword 1234] ;对于棘手的代码
连接 32 位和
; 16位段
它可能会变得很毛茸茸,但重要的是要记住你
可以在您需要时获得您需要的所有控制权。