我自己的即兴编译器错误

时间:2013-12-18 11:59:43

标签: assembly compiler-construction x86-64 nasm

我正在使用Monodevelop在Linux上使用C#构建C语言编译器。 我的编译器从文件中读取文本并输出到程序集。 现在我首先要注意的是,我得到的问题不是C#问题,而是汇编误解。我正在使用nasm汇编程序和gcc链接器。 这是输出组件:

extern printf
extern strcpy
extern systemsame
extern readinput
extern getdest
section .text
global main
jmp main_over
main:
push rax
mov rax, 0
mov rax, 1
mov byte [a], al
pop rax
push rax
mov rax, 0
mov rax, 0
mov byte [b], al
pop rax
IF_STATEMENT_0:
cmp byte [a] , 1
jne IF_STATEMENT_0_over
mov rdi, QUOTE_0
mov rax, 0
call printf
ret
main_over: 
IF_STATEMENT_1:
cmp byte [a] , 0
jne IF_STATEMENT_1_over
mov rdi, QUOTE_1
mov rax, 0
call printf
ret
IF_STATEMENT_1_over: 
IF_STATEMENT_2:
cmp byte [a] , b
jne IF_STATEMENT_2_over
mov rdi, QUOTE_2
mov rax, 0
call printf
ret
IF_STATEMENT_2_over: 
IF_STATEMENT_3:
cmp byte [a], 0
je IF_STATEMENT_3
mov rdi, QUOTE_3
mov rax, 0
call printf
ret
IF_STATEMENT_3_over: 
IF_STATEMENT_4:
cmp byte [b], 0
je IF_STATEMENT_4
mov rdi, QUOTE_4
mov rax, 0
call printf
ret
IF_STATEMENT_4_over: 
ret
IF_STATEMENT_0_over: 
section .bss
a: resb 1
b: resb 1
tempbyte: resb 20
tempword: resw 20
tempdword: resd 20

section .data

;Passon extra bit from parsing state;;;
QUOTE_0: db "a is 1!", 0
QUOTE_1: db "a is 0!", 0
QUOTE_2: db "a is b!", 0
QUOTE_3: db "a is true!", 0
QUOTE_4: db "b is true!", 0

我使用nasm汇编程序编译它并获得 NO 错误和 NO 警告。 然后,我获得一个目标代码(.o)文件,并将其与另一个工作(已测试)目标代码文件(其中包含systemsame()readinput()的定义相关联和getdest()) 使用gcc。我收到以下奇怪的错误:

In function `IF_STATEMENT_1_over':
outout.asm:(.text+0x71): relocation truncated to fit: R_X86_64_8 against `.bss'
collect2: error: ld returned 1 exit status

1 个答案:

答案 0 :(得分:3)

在我看来,错误可能是cmp byte [a] , b,因为它恰好位于错误消息中提到的标签之后,并且涉及.bss中定义的符号,错误消息中提到的部分。该指令本身对我来说很可疑,但确切的错误并不十分清楚:也许b的地址被用作立即数,这将涉及将其截断为8位。

仔细检查这实际上是您想要的翻译。我怀疑您应该将b的值加载到备用寄存器中,然后将其用作cmp的第二个操作数。

作为旁注,您应该为函数内部的基本块使用“本地”标签。否则,汇编程序将浪费时间和空间来创建无用的重定位。通常这只涉及以某种方式为这些标签添加前缀。例如,对于GNU as,它是.L - 请参阅您要定位的汇编程序手册。