如何查看 Ziglang 程序的汇编输出?

huangapple go评论116阅读模式
英文:

How do I look at the assembly output of a Ziglang program?

问题

Zig版本

0.11.0-dev.3299+34865d693

问题

我希望能够查看程序的汇编输出,最好包括文件名和行号与汇编指令的映射,以便我可以快速推断出它们来自哪里。

项目中的文件

build.zig

  1. const std = @import("std");
  2. pub fn build(b: *std.Build.Builder) !void {
  3. // 确定编译目标
  4. const target = b.standardTargetOptions(.{});
  5. // 设置优化选项
  6. const optimize = b.standardOptimizeOption(.{});
  7. // 为我们的示例创建可执行文件
  8. const exe = b.addExecutable(.{
  9. .name = "app",
  10. .root_source_file = .{ .path = "main.zig" },
  11. .target = target,
  12. .optimize = optimize,
  13. });
  14. // 在调用“zig build”时将可执行文件安装到前缀中
  15. b.installArtifact(exe);
  16. }

main.zig

  1. const std = @import("std");
  2. pub fn main() void {
  3. std.debug.print("Hello, {s}!\n", .{"World"});
  4. }
英文:

Zig version

0.11.0-dev.3299+34865d693

The problem

I want to be able to see the assembly output of my program, ideally with file names and line numbers mapping to the assembly instructions so I can quickly reason about where they've come from.

Files in project

build.zig

  1. const std = @import("std");
  2. pub fn build(b: *std.Build.Builder) !void {
  3. // Determine compilation target
  4. const target = b.standardTargetOptions(.{});
  5. // Setup optimisation settings
  6. const optimize = b.standardOptimizeOption(.{});
  7. // Create executable for our example
  8. const exe = b.addExecutable(.{
  9. .name = "app",
  10. .root_source_file = .{ .path = "main.zig" },
  11. .target = target,
  12. .optimize = optimize,
  13. });
  14. // Install the executable into the prefix when invoking "zig build"
  15. b.installArtifact(exe);
  16. }

main.zig

  1. const std = @import("std");
  2. pub fn main() void {
  3. std.debug.print("Hello, {s}!\n", .{"World"});
  4. }

答案1

得分: 3

更新你的 build.zig 文件以通过将以下内容添加到构建设置来生成汇编代码。这将使 Zig 生成一个名为 "app.s" 的文件。

  1. // 获取构建的汇编输出
  2. exe.emit_asm = .emit;

据我所知,目前似乎没有办法获取与汇编指令相关联的文件名和行号。

完整示例:

  1. const std = @import("std");
  2. pub fn build(b: *std.Build.Builder) !void {
  3. // 确定编译目标
  4. const target = b.standardTargetOptions(.{});
  5. // 设置优化选项
  6. const optimize = b.standardOptimizeOption(.{});
  7. // 为我们的示例创建可执行文件
  8. const exe = b.addExecutable(.{
  9. .name = "app",
  10. .root_source_file = .{ .path = "main.zig" },
  11. .target = target,
  12. .optimize = optimize,
  13. });
  14. // 在调用 "zig build" 时将可执行文件安装到前缀中
  15. b.installArtifact(exe);
  16. // 获取构建的汇编输出
  17. exe.emit_asm = .emit;
  18. }

汇编输出片段:

  1. main.main:
  2. .Lfunc_begin6:
  3. .cv_func_id 8
  4. .cv_file 5 "C:\\ZigProjects\\hello-world\\main.zig"
  5. .cv_loc 8 5 3 0
  6. .seh_proc main.main
  7. push rbp
  8. .seh_pushreg rbp
  9. sub rsp, 32
  10. .seh_stackalloc 32
  11. lea rbp, [rsp + 32]
  12. .seh_setframe rbp, 32
  13. .seh_endprologue
  14. .Ltmp22:
  15. .cv_loc 8 5 4 20
  16. call debug.print__anon_2816
  17. nop
  18. add rsp, 32
  19. pop rbp
  20. ret
英文:

Update your build.zig to emit assembly by adding the following to your build settings. This will make Zig output an "app.s" file.

  1. // Get assembly output of build
  2. exe.emit_asm = .emit;

As far as I know, there's seemingly no way to get file names and line numbers associated with the assembly instructions at this time.

Full example:

  1. const std = @import("std");
  2. pub fn build(b: *std.Build.Builder) !void {
  3. // Determine compilation target
  4. const target = b.standardTargetOptions(.{});
  5. // Setup optimisation settings
  6. const optimize = b.standardOptimizeOption(.{});
  7. // Create executable for our example
  8. const exe = b.addExecutable(.{
  9. .name = "app",
  10. .root_source_file = .{ .path = "main.zig" },
  11. .target = target,
  12. .optimize = optimize,
  13. });
  14. // Install the executable into the prefix when invoking "zig build"
  15. b.installArtifact(exe);
  16. // Get assembly output of build
  17. exe.emit_asm = .emit;
  18. }

Snippet of assembly output:

  1. main.main:
  2. .Lfunc_begin6:
  3. .cv_func_id 8
  4. .cv_file 5 "C:\\ZigProjects\\hello-world\\main.zig"
  5. .cv_loc 8 5 3 0
  6. .seh_proc main.main
  7. push rbp
  8. .seh_pushreg rbp
  9. sub rsp, 32
  10. .seh_stackalloc 32
  11. lea rbp, [rsp + 32]
  12. .seh_setframe rbp, 32
  13. .seh_endprologue
  14. .Ltmp22:
  15. .cv_loc 8 5 4 20
  16. call debug.print__anon_2816
  17. nop
  18. add rsp, 32
  19. pop rbp
  20. ret

答案2

得分: 0

除了上面的答案之外,如果想要逐步查看发生的确切情况,你可以随时使用 gdb 调试反汇编代码。

英文:

in addition to the answer above you can always debug the disassembly using gdb if want to walk through and see what happens exactly.

huangapple
  • 本文由 发表于 2023年5月28日 08:37:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76349547.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定