Assembly 您好,世界与TCC使用汇编语言?

Assembly 您好,世界与TCC使用汇编语言?,assembly,tcc,Assembly,Tcc,我不懂汇编语言,在我的学校,他们这样做只是为了说明什么是汇编语言以及如何编译 你们能给我一些基本的hello world示例,使用汇编语言运行tccasm吗 感谢您的帮助这里是一个32位Windows hello world: .global main .section .text main: leal message, %eax pushl %eax // the C convention is params are pushed onto the stack

我不懂汇编语言,在我的学校,他们这样做只是为了说明什么是汇编语言以及如何编译

你们能给我一些基本的hello world示例,使用汇编语言运行tccasm吗


感谢您的帮助

这里是一个32位Windows hello world:

.global  main

.section .text
main:
    leal    message, %eax
    pushl   %eax // the C convention is params are pushed onto the stack
    call    printf
    popl    %eax // and the caller is responsible for cleanup
    pushl   $0
    call    exit
    hlt // never reached
.data
message:
    .string  "Hello, world!\n\0"
使用以下内容构建:
tcc test.s-lmsvcrt
(文件名必须以.s结尾,tcc才能将其识别为asm文件)

它调用C函数来完成这项工作。您也可以仅使用Windows功能:

.global  main

.section .text
main:
    pushl $-11 // STD_OUTPUT_HANDLE
    call GetStdHandle // the return value will be in eax

    // now we'll call WriteFile. Args are pushed from right to left
    pushl $0 // lpOverlapped == null, don't want async
    pushl $0 // lpNumberOfBytesWritten == null, we don't care
    pushl $14 // nNumberOfBytesToWrite, our hello world has 14 chars.
    leal message, %ebx // load address for lpBuffer, pointer to the string to write
    pushl %ebx // and push it to the stack
    pushl %eax // the return value we got from GetStdHandle
    call WriteFile // and write the file
    // unlike the C convention, the Windows functions clean up their own stack
    // so we don't have to pop that stuff

    // and now we'll call ExitProcess to get out
    pushl   $0 // our main's return value of 0 == success
    call    ExitProcess
    hlt // never reached
.data
message:
    .string  "Hello, world!\n\0"// so we don't have to pop that stuff

// and now we'll call ExitProcess to get out
    pushl   $0
    call    ExitProcess
    hlt // never reached
.data
message:
    .string  "Hello, world!\n\0"
这里不需要C库,因此使用一个简单的
tcc test.s
构建,当您从控制台运行它时,您应该会看到其中的消息

有趣的事实:Windows功能非常容易使用,您可以简单地弹出一个消息框:

.global  main

.section .text
main:
    pushl $0 // MB_OK
    pushl $0 // title = null (will use the default of "Error")
    leal message, %eax // load our message
    pushl %eax // and push the string pointer to the argument list
    pushl $0 // hwnd == null, no owning window
    call MessageBoxA // and pop up the message box
    pushl   $0
    call    ExitProcess
    hlt // never reached
.data
message:
    .string  "Hello, world!\n\0" // don't forget the zero terminator!
MessageBoxA是在user32中找到的,因此使用
tcc test.s-luser32构建,然后运行,您将得到它

这都是win32,因为我不太了解win64,但32位程序应该仍然可以正常工作,您可以使用它。tcc使用的AT&T汇编程序语法并不常见,但要将nasm或大多数其他汇编程序的英特尔语法转换为它,请记住:

  • 它需要指令上的长度后缀。因此,当按下长的,即32位的值时,
    push
    而不是
    push

  • 立即数(文本数)的前缀为$。实际上,现在我写了这个,我意识到我可以写上面的
    pushl$message
    ,而不是两步
    leal消息,%eax pushl%eax
    。哦,两种方法都有效。但是,如果您忘记了$,它会尝试将其用作指针,在加载内容时,您可能会看到在外观较小的内存地址上非法读/写

  • 注册名称需要%前缀

  • 它指向source,destination,这与英特尔语法的destination,source相反。(我作为一个新手学习了英特尔的方法,所以AT&T的语法对我来说是落后的!)

但如果您还记得这四个不同之处,您就可以相当容易地将Intel语法代码转换为tcc的AT&T语法代码。一个微小的变化是tcc使用C风格的注释(
//comment
),而大多数其他汇编程序使用
;命令

tcc的另一个特点是不必声明外部函数,也不必使用参数长度后缀或下划线前缀。尽管ASCII或宽后缀必须存在,但您编写它的方式与C语言几乎相同(这些是C中的宏;
#定义MessageBox MessageBoxA
,因此在Windows标题中,如果使用unicode支持编译,则将A改为W。区别在于A版本采用ascii字符串-每个字符8位,无法访问所有字符,而W版本采用16位unicode字符串。)

旁注:Win32函数的实际损坏名称如下_MessageBoxA@16.您可以看到,正如我刚才提到的,我们在示例代码中使用了“A”,但没有使用u或@16。这些名称位对C隐藏,用于帮助捕获错误数量的参数-@16表示消息框I需要16字节的参数n 32位,即hwnd(4,hwnd)、指向消息的指针(4,char*)、指向标题的指针(4,char*)和标志(4,一个int)。如果您在internet上看到带有这些更改的调用函数的示例代码,这就是它存在的原因,而tcc不需要它


这应该让你开始了!

不,我正在使用64位windows 7,你能帮我吗?:Dhmm,我的windows是32位的,但我确信它仍然可以工作。我会发布一些代码。我尝试了你的代码,但在第6行有一个小错误,它说“未知操作码:PUSH”可能是因为我的tcc太旧了……我的是tcc版本0.9.26。(编辑,互联网告诉我这是最新的版本…)但是,你有什么版本?我可以得到相同的版本并更新答案。用“推”代替“推”也可以.我最近刚下载的,应该是一样的,对吧?是的,我尝试了push,但仍然没有luckrun tcc没有参数,检查输出的第一行版本号EP是一样的,我的是0.9.26