V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
find456789
V2EX  ›  问与答

c 语言是基于汇编的,那么这么多年的积累了,能否基于汇编开发一个比 c 更好的语言,或者这些年 汇编和 c 语言之间的 架构是保持升级的吗? 或者还是很多年前的那一套?

  •  
  •   find456789 · 2020-12-05 17:29:57 +08:00 · 3422 次点击
    这是一个创建于 1479 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我了解到,c 语言是基于汇编语言的

    当开发出了第一个版本的 c 语言, 接着在第一个版本的 c 上 ,用 c 开发第二个版本的 c, 以此类推

    我的理解是,这里面应该会有一些老旧的代码在 c 里(即架构、性能落后的代码)

    1 、我想问问,这些年来, 汇编和 c 语言之间的桥梁有保持更新吗? 或者还是很多年前的那一套呢?

    2 、 能否基于汇编开发一个比 c 更好的语言? 工作量大吗?有什么参考资料来自学吗?

    谢谢

    27 条回复    2020-12-06 10:37:18 +08:00
    jmc891205
        1
    jmc891205  
       2020-12-05 17:48:01 +08:00 via iPhone   ❤️ 3
    C++表示楼主想法很赞
    cmostuor
        2
    cmostuor  
       2020-12-05 18:04:32 +08:00
    C 语言的基础是 B 语言, B 语言的基础则是 Fortran 编译器+BCPL 风格而发展成的. 资料来自维基百科
    creedowl
        3
    creedowl  
       2020-12-05 18:04:52 +08:00 via Android
    现在语言前端后端早就分开了,建议看看 llvm
    SuperMild
        4
    SuperMild  
       2020-12-05 18:10:48 +08:00
    基于啥并不重要。没有什么语言比 C 更好或更差,因为你不能说剪刀比螺丝刀更好。
    ho121
        5
    ho121  
       2020-12-05 18:13:10 +08:00 via Android
    rust ?
    msg7086
        6
    msg7086  
       2020-12-05 18:41:58 +08:00
    汇编是汇编,编译语言是编译语言,不要混为一谈。
    而且语言是语言,编译器是编译器,也不要混为一谈。
    只要你想,拿 PHP 开发一个 C 编译器都是可以的,毕竟代码生成并没有需要用到汇编的地方。
    (打个可能不恰当的比方,开发 Photoshop 的人不一定要会画画。)
    用 C 的话,方便维护,然后还可以自举。
    cmostuor
        7
    cmostuor  
       2020-12-05 19:03:52 +08:00   ❤️ 1
    @cmostuor 补充
    1 汇编语言是与指令集对应的
    2 没有一门高级语言是基于汇编开发的, 现在的高级语言是直接编译成字节码 没有转换成汇编的过程.
    Cbdy
        8
    Cbdy  
       2020-12-05 19:09:10 +08:00 via Android
    写个前端本来就很简单了
    FutherAll
        9
    FutherAll  
       2020-12-05 19:16:00 +08:00 via iPhone   ❤️ 1
    汇编和编程语言没有关系吧,想要的话完全可以自己写编译器实现「高级语言--汇编--机器码」的过程
    natforum
        10
    natforum  
       2020-12-05 19:26:22 +08:00
    rust 表示这个想法很好
    CEBBCAT
        11
    CEBBCAT  
       2020-12-05 19:49:51 +08:00 via Android
    @cmostuor 啊?怎么会没有翻译到汇编的过程?在用 Go,确实有
    CEBBCAT
        12
    CEBBCAT  
       2020-12-05 19:51:45 +08:00 via Android   ❤️ 1
    @CEBBCAT 续:在用 Go,确实有编译到汇编这一步呀 https://colobu.com/2018/12/29/get-assembly-output-for-go-programs/

    你是在说 Java 吗?
    WebKit
        13
    WebKit  
       2020-12-05 19:58:04 +08:00 via Android
    @cmostuor 字节码,感觉是 java 那一套
    OysterQAQ
        14
    OysterQAQ  
       2020-12-05 20:05:15 +08:00   ❤️ 1
    汇编又叫助记符 已经很接近 cpu 指令了 现在编译器也有很多种啊 也都很智能
    levelworm
        15
    levelworm  
       2020-12-05 20:06:35 +08:00 via Android
    @WebKit 我感觉他想说的是 CPU 本质上就是个大虚拟机
    Ayahuasec
        16
    Ayahuasec  
       2020-12-05 20:41:32 +08:00   ❤️ 1
    我记得 go 好像哪一个版本之前要用 c 来编译,过了那个版本之后就可以自己编译自己的新版本了,或许可以类比一下?
    毕竟只是把语言本来的语法翻译成及其可识别的字节码,功能上看和其他程序的把输入数据转换成输出数据并没有太大区别,最开始没有工具的时候被迫用汇编,汇编创造出了工具,那之后再用工具创造新的工具就行了
    find456789
        17
    find456789  
    OP
       2020-12-05 21:03:18 +08:00
    @creedowl 大哥你好, 用 llvm 开发新语言,是不是要掌握 c\c++ 我看网上的资料 似乎是这样的
    cmostuor
        18
    cmostuor  
       2020-12-05 21:06:17 +08:00
    @Ayahuasec go 1.3.x 之前是用 C 语言编译
    irytu
        19
    irytu  
       2020-12-05 21:08:22 +08:00 via iPhone   ❤️ 1
    c 语言是基于汇编 这个说法不对,C 语言是为了更友好开发者,在编码上是更高一层的抽象,也就是你不用关心具体指令架构方面的事情,那是编译器的工作;再有汇编是跟架构指令集强相关的,而 C 不是。基本概念不能出偏差
    cmostuor
        20
    cmostuor  
       2020-12-05 21:24:19 +08:00
    这是龙芯 CPU AUL 模块 的指令集一小部分

    cpu_gs232/blob/master/global.h

    /*Fix point operation*/
    `define OP_CLO 8'H00
    `define OP_CLZ 8'H01
    `define OP_EXT 8'H02
    `define OP_INS 8'H03
    `define OP_WSBH 8'H04
    `define OP_ROTR 8'H06 //include ROTRV
    `define OP_SEB 8'H08
    `define OP_SEH 8'H09
    `define OP_MOVN 8'H0a
    `define OP_MOVZ 8'H0b
    `define OP_MFHI 8'H0c
    `define OP_MFLO 8'H0d
    `define OP_MTHI 8'H0e
    `define OP_MTLO 8'H0f
    `define OP_MUL 8'H10
    `define OP_SLL 8'H11 //include NOP,SSNOP,EHB,SLLV
    `define OP_SRL 8'H12 //SRLV
    `define OP_SRA 8'H13
    `define OP_MULT 8'H14
    `define OP_MULTU 8'H15
    `define OP_DIV 8'H16
    `define OP_DIVU 8'H17
    `define OP_ADD 8'H18 //ADDI
    `define OP_ADDU 8'H19 //ADDIU, LUI, RDPGPR, WRPGPR
    `define OP_SUB 8'H1a
    `define OP_SUBU 8'H1b
    `define OP_AND 8'H1c //ANDI
    `define OP_OR 8'H1d //ORI
    `define OP_XOR 8'H1e //XORI
    `define OP_NOR 8'H1f
    `define OP_TEQ 8'H20 //TEQI
    `define OP_TNE 8'H21 //TNEI
    `define OP_TLT 8'H22 //TLTI
    `define OP_TLTU 8'H23 //TLTIU
    `define OP_TGE 8'H24 //TGEI`
    `define OP_TGEU 8'H25 //TEEI
    `define OP_SLT 8'H26 //SLTI
    `define OP_SLTU 8'H27 //SLTIU
    `define OP_MADD 8'H28
    `define OP_MADDU 8'H29
    `define OP_MSUB 8'H2a
    `define OP_MSUBU 8'H2b
    `define OP_J 8'H2c
    `define OP_JR 8'H2d //JR.HB
    `define OP_JAL 8'H2e
    `define OP_JALR 8'H2f //JALR.HB
    `define OP_BEQ 8'H30
    `define OP_BNE 8'H31
    `define OP_BLEZ 8'H32
    `define OP_BGTZ 8'H33
    `define OP_BLTZ 8'H34
    `define OP_BGEZ 8'H35
    `define OP_BLTZAL 8'H36
    `define OP_BGEZAL 8'H37
    `define OP_BEQL 8'H38
    `define OP_BNEL 8'H39
    `define OP_BLEZL 8'H3a
    `define OP_BGTZL 8'H3b
    `define OP_BLTZL 8'H3c
    `define OP_BGEZL 8'H3d
    `define OP_BLTZALL 8'H3e
    `define OP_BGEZALL 8'H3f

    cpu_gs232/blob/master/godson_alu_module.v

    reg [31:0]bresult;
    always @(sub_op or bsum_0 or bsum_1 or bsum_2 or bsum_3 or a or b or blt or eq_4 or op
    or braddu_temp or pick_0 or pick_1 or pick_2 or pick_3) begin
    case(op) // synopsys full_case parallel_case

    /*ADDU.QB*/
    `OP_ADDQ :
    bresult = {bsum_3[7:0],bsum_2[7:0],bsum_1[7:0],bsum_0[7:0]};

    /*ADDU_S.QB*/
    `OP_ADDQ_S :
    bresult = {bsum_3[8] ? 8'hff : bsum_3[7:0], bsum_2[8] ? 8'hff : bsum_2[7:0],
    bsum_1[8] ? 8'hff : bsum_1[7:0], bsum_0[8] ? 8'hff : bsum_0[7:0]};

    `OP_SUBQ :
    /*SUBU.QB*/
    bresult = {bsum_3[7:0],bsum_2[7:0],bsum_1[7:0],bsum_0[7:0]};

    `OP_SUBQ_S :
    /*SUBU_S.QB*/
    bresult = {bsum_3[8] ? 8'h00 : bsum_3[7:0],
    bsum_2[8] ? 8'h00 : bsum_2[7:0],
    bsum_1[8] ? 8'h00 : bsum_1[7:0],
    bsum_0[8] ? 8'h00 : bsum_0[7:0]};

    `OP_RADDU :
    //bresult = {22'b0, braddu_temp}; nomatch
    bresult = {21'b0, braddu_temp};

    `OP_CMP_EQ :
    /*CMPGU.EQ.QB , CMPU.EQ.QB*/
    bresult = {28'h0, eq_4[3], eq_4[2],eq_4[1],eq_4[0]};

    `OP_CMP_LT :
    /*CMPGU.LT.QB , CMPU.LT.QB*/
    bresult = {28'h0, blt[3], blt[2], blt[1], blt[0]};

    //8'hde :
    `OP_CMP_LE :
    /*CMPGU.LE.QB , CMPU.LE.QB*/
    bresult = {28'h0, (blt[3]|eq_4[3]), (blt[2]|eq_4[2]), (blt[1]|eq_4[1]), (blt[0]|eq_4[0])};

    `OP_PICK :
    bresult = {pick_3, pick_2, pick_1, pick_0};

    `OP_PRECEQU_PH_QBL :
    /*PRECEQU_PH_QBL*/
    bresult = {{1'b0, a[31:24], 7'b0}, {1'b0, a[23:16], 7'b0}};

    `OP_PRECEQU_PH_QBR :
    /*PRECEQU_PH_QBR*/
    bresult = {{1'b0, a[15:8], 7'b0}, {1'b0, a[7:0], 7'b0}};

    `OP_PRECEQU_PH_QBLA :
    /*PRECEQU_PH_QBLA*/
    bresult = {{1'b0, a[31:24], 7'b0}, {1'b0, a[15:8], 7'b0}};

    `OP_PRECEQU_PH_QBRA :
    /*PRECEQU_PH_QBRA*/
    bresult = {{1'b0, a[23:16], 7'b0}, {1'b0, a[7:0], 7'b0}};

    `OP_PRECEU_PH_QBL :
    /*PRECEU_PH_QBL*/
    bresult = {{8'b0, a[31:24]}, {8'b0, a[23:16]}};

    `OP_PRECEU_PH_QBR :
    /*PRECEU_PH_QBR*/
    bresult = {{8'b0, a[15:8]}, {8'b0, a[7:0]}};

    `OP_PRECEU_PH_QBLA :
    /*PRECEU_PH_QBLA*/
    bresult = {{8'b0, a[31:24]}, {8'b0, a[15:8]}};

    `OP_PRECEU_PH_QBRA :
    /*PRECEU_PH_QBRA*/
    bresult = {{8'b0, a[23:16]}, {8'b0, a[7:0]}};

    // `OP_REPL :
    /*REPL(V).QB*/
    default :
    bresult = {a[7:0], a[7:0], a[7:0], a[7:0]};
    endcase
    end //end always
    creedowl
        21
    creedowl  
       2020-12-05 21:38:12 +08:00 via Android
    @find456789 简单来说 llvm 是将中间语言编译成机器码用的,c c 艹这些都可以编译到 llvm 用的中间语言,所以想开发一个新语言写个编译器将它编译成中间语言就可以了,具体可以学学编译原理
    icegaze
        22
    icegaze  
       2020-12-05 22:12:21 +08:00 via Android   ❤️ 1
    我感觉,
    高级语言是面对人的,
    低级语言是面对机器的,
    中间还差着一个操作系统呢…
    汇编可以看作机器码的简易代替写法,
    而 C 语言可以看作一种人能理解的伪语言。

    不能说 C 语言并不是基于汇编语言的吧…

    甚至如果充分理解 cpu 构架和操作系统里的各种驱动的话,也可以直接用 HEX 编辑器来写出一个机器码程序了吧…^_^
    find456789
        23
    find456789  
    OP
       2020-12-05 22:18:30 +08:00
    @creedowl

    哦 谢谢大哥, 那我用其他语言 比如 js 、go 、python,试试也可以 在 llvm 上 开发一门新语言呀
    creedowl
        24
    creedowl  
       2020-12-05 23:24:46 +08:00
    @find456789 #23 理论上是可以的
    CEBBCAT
        25
    CEBBCAT  
       2020-12-05 23:40:49 +08:00   ❤️ 2
    我读了 @creedowl 的回复,然后 Google 了一些关键词,花了半个小时,看了大概四五十个页面后做这个回复:

    假如楼主想借由 llvm 开发一门新的语言,那么你的目标是 IR,也就是中间语言,那么结合其他语言自举的经验, 你可以使用任何一门你喜欢的语言实现一个 llvm 前端,用来把你的新语言—我们不妨叫它 X 语言—翻译到 IR,你甚至可以手写出新语言的 IR,我是这样理解的

    附上一些可能有帮助的链接,你可以在里面拣选感兴趣的词,去 Google:
    https://draveness.me/dsl/
    https://blog.csdn.net/yayaayaya123/article/details/83993041
    https://segmentfault.com/a/1190000002669213
    https://zh.wikipedia.org/wiki/%E4%B8%AD%E9%96%93%E8%AA%9E%E8%A8%80
    https://en.wikipedia.org/wiki/Three-address_code
    https://blog.csdn.net/BaiHuaXiu123/article/details/89377250
    ---
    看完这些网页后,我想我也可以“指点”一下你的正文了:
    今天的 gcc 编译器可以做到不留存“老旧的代码(即架构、性能落后的代码)”,因为 gcc 这个二进制是从它的源码来的,不是一个套娃的关系
    find456789
        26
    find456789  
    OP
       2020-12-06 00:51:40 +08:00
    @CEBBCAT

    谢谢大哥
    whywhywhy
        27
    whywhywhy  
       2020-12-06 10:37:18 +08:00
    c
    c++
    c++++( c#)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3270 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 12:03 · PVG 20:03 · LAX 04:03 · JFK 07:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.