2011-12-06 33 views
3

所以我通過傳遞給主則ARGS循環簡單的C程序返回:不GCC真的知道如何輸出NASM大會

#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 

.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 

在命令行上的錯誤是:

[[email protected] 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人,字節的ptr [DS:SI]或MOV AX,字的ptr [DS:SI]或MOV EAX, DWORD PTR [DS:SI]

對於NASM這簡單地說成:

MOV人,字節[DS:SI]或MOV AX,字[DS:SI]或MOV EAX,DWORD [DS:SI]

NASM允許這些尺寸中的關鍵字許多地方,因此給你一個 很多控制ov呃生成的操作碼以unifrom的方式,對於 示例這些全部有效:

push dword 123 jmp [ds:word 1234];這些都指定偏移量jmp [ds:dword 1234]的大小 ;爲 連接32位和 時的棘手代碼; 16位段

它可以變得很毛茸茸的,但重要的是要記住的是,當你需要它時,你可以擁有所有你需要的控制。

回答

7

Intel語法表示Intel語法,不是NASM語法。 MASM和TASM語法基於英特爾語法,NASM語法從英特爾語法中獲得靈感,但它不同。

什麼gcc的輸出,實際上是採用了Intel語法各個指令氣體語法,(彙編指令,標籤等。使用氣體特定的語法)

+0

你知道的,隨着氣語法涉及任何書籍或在線信息?你也知道什麼彙編語法微軟的cl.exe輸出? –

+0

@MatthewHoggan:氣體語法在氣體手冊中有描述:http://sourceware.org/binutils/docs-2.22/as/Syntax.html#Syntax,但正如我所說的,個別指令採用Intel語法。 – ninjalj