C break指令中的汇编代码获取当前时间

Assembly code in C break instruction to get current time

我需要用 C 语言编写内联汇编代码,格式如下:

asm(
    "mov %1, %%ax\n\t"
    "inc %%ax\n"
    "mov %%ax, %0"
    :"=r" (a)
    :"r" (a)
    );

asm() 中的这段代码需要中断并将当前时间分配给在 asm() func 之外的 C 中声明的变量。我曾尝试编写自己的代码,但我什至难以执行中断指令……我在使用英特尔并使用代码块。也欢迎任何好的内联汇编资源。 编辑:我需要这样的东西:

int 21h -> break
AH = 2Ah
CX -> year
DH -> month
DL -> day
AH = 2Ch
CH -> hour
CL -> min
DH -> sec
RET

一般来说,在 x86 上使用 gcc 内联 asm 时,您绝对不想在 asm 代码中包含 mov 指令或显式寄存器。相反,您想使用约束来强制输入和输出到特定的寄存器。可用的约束是:

+---+--------------------+
| r |    Register(s)     |
+---+--------------------+
| a |   %eax, %ax, %al   |
| b |   %ebx, %bx, %bl   |
| c |   %ecx, %cx, %cl   |
| d |   %edx, %dx, %dl   |
| S |   %esi, %si        |
| D |   %edi, %di        |
+---+--------------------+

这意味着您的增量示例(将值放入 ax 并递增)可以更有效地写为:

asm("inc %0" : "+a" (a))

这会强制变量 a 进入 ax 寄存器(假设它是一个 16 位值)并在那里递增它。

一个棘手的问题是 h 寄存器(16 位寄存器的高 8 位)没有限制。所以如果你想用这些做事,你需要使用一个 16 位值并明确 pack/unpack 对。所以对于你的 int 21h/2Ah 电话,你会使用类似的东西:

uint16_t year, month_day;
asm("int 0x21" : "=c" (year), "=d" (month_day) : "a" (0x2a00));
uint8_t month = month_day >> 8;
uint8_t day = month_day;