我正在尝试生成 16 位 DOS 可执行文件,但使用 gcc 编译器。所以我使用的是古老的 gcc-4.3 ia16 端口。我为我的构建制作了一个 Docker 映像:https ://registry.hub.docker.com/u/ysangkok/ia16-gcc-rask
这是我正在尝试的:
host $ mkdir results
host $ docker run -v $PWD/results:/results -it ysangkok/ia16-gcc-rask
container $ cd results
我不包含标头,因为 gcc 不能使用 OpenWatcom 的 libc 标头。
container $ echo 'main() { printf("lol"); }' > test.c
我没有链接,因为我没有可用的 16 位 binutils。如果我构建一个目标文件,它没有正确标记为 16 位。
container $ /trunk/build-ia16-master/prefix/bin/ia16-unknown-elf-gcc -S test.c
现在我有这个程序集文件:
.arch i8086,jumps
.code16
.att_syntax prefix
#NO_APP
.section .rodata
.LC0:
.string "lol"
.text
.p2align 1
.global main
.type main, @function
main:
pushw %bp
movw %sp, %bp
subw $4, %sp
call __main
movw $.LC0, %ax
pushw %ax
call printf
addw $2, %sp
movw %bp, %sp
popw %bp
ret
.size main, .-main
.ident "GCC: (GNU) 4.3.0 20070829 (experimental)"
在容器之外,在主机中,我尝试用 yasm 组装它:
% yasm -m x86 -p gas -f elf -o test.o test.s
test.s:1: warning: directive `.arch' not recognized
test.s:3: error: junk at end of line, first unrecognized character is `p'
yasm看不懂,我把语法行注释掉,再试一次,这次成功了。
我测试重定位符号:
% objdump -r test.o
test.o: file format elf32-i386
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000007 R_386_PC16 __main
0000000a R_386_16 .rodata
0000000e R_386_PC16 printf
可悲的是,它们是 32 位的。当我尝试在容器中进行链接时,它不起作用:
root@1341f35c4590:/# cd ow/binl/
root@1341f35c4590:/ow/binl# WATCOM=/ow /ow/binl/wlink
Open Watcom Linker Version 1.9
Portions Copyright (c) 1985-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
Press CTRL/D to finish
WLINK>system dos
WLINK>file /results/test.o
[ comment: i press control-d on the next line ]
WLINK>loading object files
Warning! W1080: file /results/test.o is a 32-bit object file
Error! E2015: file /results/test.o(test.s): bad relocation type specified
Error! E2015: file /results/test.o(test.s): bad relocation type specified
Error! E2015: file /results/test.o(test.s): bad relocation type specified
如果我尝试制作 COFF 而不是 ELF,yasm 甚至无法组装:
root@1341f35c4590:/# cd ow/binl/
root@1341f35c4590:/ow/binl# WATCOM=/ow /ow/binl/wlink
Open Watcom Linker Version 1.9
Portions Copyright (c) 1985-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
Press CTRL/D to finish
WLINK>system dos
WLINK>file /results/test.o
WLINK>loading object files
Warning! W1080: file /results/test.o is a 32-bit object file
Error! E2015: file /results/test.o(test.s): bad relocation type specified
Error! E2015: file /results/test.o(test.s): bad relocation type specified
Error! E2015: file /results/test.o(test.s): bad relocation type specified
我知道 yasm 不支持 16 位,但也许有解决方法?有兼容 GAS 的 16 位汇编器吗?GAS-to-Intel 转换器不工作。