【发布时间】:2020-05-14 07:50:02
【问题描述】:
我在 Ubuntu 18.04 X86_64 中测试一个 X86 汇编代码如下,
#define I8042_DATA_REG $0x60
#define I8042_STATUS_REG $0x64
.globl flashy
.text
/* Flash 16 times */
movl $0x10, %ebx
flashy:
/* Turn on LEDs, don't trust stack at this point */
1: inb I8042_STATUS_REG, %al
testb $0x02, %al
jne 1b
movb $0xed, %al
outb %al, I8042_DATA_REG
movl $0x1000, %eax
1: subl $1, %eax
cmpl $0, %eax
jne 1b
1: inb I8042_STATUS_REG, %al
testb $0x02, %al
jne 1b
movl $0x1000, %eax
1: subl $1, %eax
cmpl $0, %eax
jne 1b
/* LEDs ON */
movb $0x07, %al
outb %al, I8042_DATA_REG
/* delay */
movl $0x07878787, %eax
1: subl $1, %eax
cmpl $0, %eax
jne 1b
sub $1, %ebx
cmpl $0, %ebx
jne flashy
我编写了一个简单的 main.c 来调用上述程序集中的 flashy() 函数。
extern void flashy(void);
int main()
{
flashy();
return 0;
}
我将它们编译为,
gcc -S test.S -o test.o
gcc -c main.c -o main.o
ld main.o test.o -o testmain
我从 ld 收到如下警告,
ld:警告:找不到入口符号_start;默认为 00000000004000b0
而且我无法运行生成的 testmain。
所以我想知道我在构建这个测试时错过了什么。
【问题讨论】:
-
使用
gcc代替ld进行链接,gcc将自动链接C 程序的标准库。顺便说一句,我认为您的汇编代码将无法在用户模式下工作,因为直接与硬件交互需要环 0,请考虑使用像 DosBox 这样的模拟器。 -
请在此处添加您的 main.c 代码,并显示您的构建和运行命令。
-
@KagurazakaKotori 你给了我正确的答案。根据您的评论,我还在 flashy() 周围添加了 iopl(3)/iopl(0),并且使用 gcc 我可以很好地运行此代码。您可以发布您的答案,或者我可以以您的名义发布您的答案。
-
@wangt13 请随时发布答案。
-
为什么
movl $0x10, %ebx位于flashy标签之前?此外,作为一般风格说明:标签进入第一列,没有缩进。