【问题标题】:Does gcc really know how to output NASM Assemblygcc 真的知道如何输出 NASM 程序集吗
【发布时间】:2012-01-14 10:12:47
【问题描述】:

所以我有一个简单的 C 程序,它遍历传递给 main 的 args 然后返回:

#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

命令行的错误是:

[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, byte ptr [ds:si] or mov ax, word ptr [ds:si] or mov eax, dword ptr [ds:si]

对于 NASM,这简单地转换为:

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

NASM 允许在许多地方使用这些尺寸关键字,从而为您提供 以 unifrom 方式对生成的操作码进行大量控制,例如 示例这些都是有效的:

push dword 123 jmp [ds: word 1234] ;这些都指定了大小 偏移量 jmp [ds: dword 1234] ;对于棘手的代码 连接 32 位和 ; 16位段

它可能会变得很毛茸茸,但要记住的重要一点是你 可以随心所欲地进行所需的所有控制。

【问题讨论】:

    标签: gcc nasm tasm


    【解决方案1】:

    Intel 语法是指 Intel 语法,而不是 NASM 语法。 MASM 和 TASM 语法基于 Intel Syntax,NASM 语法从 Intel 语法中获得灵感,但又有所不同。

    gcc 输出的实际上是使用 Intel 语法的单个指令的 gas 语法,(汇编程序指令、标签等使用特定于 gas 的语法)

    【讨论】:

    • 你知道有关气体语法的任何书籍或在线信息吗?你还知道微软的 cl.exe 输出什么汇编语法吗?
    • @MatthewHoggan:gas 语法在 gas 手册中有所描述:sourceware.org/binutils/docs-2.22/as/Syntax.html#Syntax,但正如我所说,个别指令采用 Intel 语法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 2016-11-27
    • 1970-01-01
    相关资源
    最近更新 更多