gcc是否真的知道如何输出NASM程序集 [英] Does gcc really know how to output NASM Assembly

查看:490
本文介绍了gcc是否真的知道如何输出NASM程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  #include  

.H>

int main(int argc,char * argv [])
{
int i;
for(i = 0; i fprintf(stdout,%s\,argv [i]);
}
返回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

  .filemain.c
.intel_syntax noprefix
.section .rodata
.LC0:
.string%s\\\

.text
.globl main
.type main,@function
main:
push ebp
mov ebp,esp
和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
.identGCC:(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:错误:尝试在任何非本地标签之前定义本地标签
main.asm:1:错误:解析器:预期的指令
main.asm :2:错误:尝试在任何非本地标签之前定义本地标签
main.asm:2:错误:解析器:预期的指令
main.asm:3:错误:尝试定义本地任何非本地标签之前的标签
main.asm:3:error:parser:inst ruction expected
main.asm:4:错误:尝试在任何非本地标签之前定义本地标签
main.asm:5:错误:尝试在任何非本地标签之前定义本地标签
main.asm:5:error:解析器:预期的指令
main.asm:6:错误:尝试在任何非本地标签之前定义本地标签
main.asm:7:错误:尝试在任何非本地标签之前定义本地标签
main.asm:7:错误:解析器:预期的指令
main.asm:8:错误:尝试在任何非本地标签之前定义本地标签非本地标签
main.asm:8:错误:解析器:预期的指令
main.asm:14:错误:逗号,冒号或行尾预期
main.asm:17:错误:逗号,冒号或行结尾预期
main.asm:19:错误:逗号,冒号或行尾预期
main.asm:20:错误:逗号,冒号或行结束符
main.asm:21:错误:逗号,冒号或行结尾预期
main.asm:22:错误:逗号,冒号或行尾预期
main.asm:23:错误:逗号,冒号或行尾预期
main.asm:24:错误:逗号,冒号或行结尾预期
main.asm:25:错误:逗号,冒号或行结尾预期
main.asm:27:错误:逗号,冒号或行结尾预期
main.asm:29:错误:逗号,冒号或行结尾预期
main.asm:30:错误:逗号,冒号或行尾预期
main.asm:35:错误:解析器:预期的指令
main.asm:36:错误:解析器:预期的指令
main.asm:37:错误:解析器:预期的指令
make:*** [main.o]错误1

让我相信这是TASM语法是发布在此链接的信息:
http://rs1.szif.hu/~tomcat/win32/intro.txt


TASM编码器通常会遇到词汇困难与NASM,因为它
缺乏广泛用于TASM的ptr关键字。



TASM使用这个:



MOV al,byte ptr [ds:si]或mov ax,word ptr [ds:si]或mov eax,
dword ptr [ds:si]

对于NASM而言,这仅仅意味着:

mov al,byte [ds:si]或mov ax,word [ds:si]或mov eax,dword
[ds:si]



NASM允许在许多地方使用这些大小关键字,因此可以以单一方式对生成的操作码进行
的大量控制,对于
示例这些都是有效的:

push dword 123 jmp [ds:word 1234];这些都指定偏移量jmp [ds:dword 1234]的大小
;对于
接口32位和
的棘手代码; 16bit的细分市场

它可以变得非常多毛,但要记住的重要一点是,当你需要时,你
可以拥有你所需要的全部控制。

So I have a simple C program that loops through the args passed to main then returns:

#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;
}

I wanted to see how gcc wrote out the assembly in NASM format. I was looking over the output in the .asm file and noticed that the syntax was TASM. Below is the make file and the output from gcc. Am I doing something wrong or is it that gcc does not output true NASM syntax?

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

The errors on the command line are:

[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

What lead me to believe that this is TASM syntax was information posted at this link: http://rs1.szif.hu/~tomcat/win32/intro.txt

TASM coders usually have lexical difficulties with NASM because it lacks the "ptr" keyword used extensively in TASM.

TASM uses this:

mov al, byte ptr [ds:si] or mov ax, word ptr [ds:si] or mov eax, dword ptr [ds:si]

For NASM This simply translates into:

mov al, byte [ds:si] or mov ax, word [ds:si] or mov eax, dword [ds:si]

NASM allows these size keywords in many places, and thus gives you a lot of control over the generated opcodes in a unifrom way, for example These are all valid:

push dword 123 jmp [ds: word 1234] ; these both specify the size of the offset jmp [ds: dword 1234] ; for tricky code when interfacing 32bit and ; 16bit segments

it can get pretty hairy, but the important thing to remember is you can have all the control you need, when you want it.

解决方案

Intel syntax means Intel syntax, not NASM syntax. MASM and TASM syntaxes are based on Intel Syntax, NASM syntax gets inspiration from Intel syntax, but it is different.

What gcc outputs is actually gas syntax using Intel syntax for individual instructions, (Assembler directives, labels et al. use gas-specific syntax)

这篇关于gcc是否真的知道如何输出NASM程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆