程序集使用不同的语法执行带偏移的跳远

编程入门 行业动态 更新时间:2024-10-27 22:31:01
本文介绍了程序集使用不同的语法执行带偏移的跳远的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在为内核编写GDT,并且一切进展顺利,我正在关注本教程.

I am writing a GDT for a Kernel and all is going well, I'm following this tutorial.

www.osdever/bkerndev/Docs/gdt.htm

将C代码链接到汇编代码时,他使用了这段代码.

When link the C code to the assembly code he uses this piece of code.

; This will set up our new segment registers. We need to do ; something special in order to set CS. We do what is called a ; far jump. A jump that includes a segment as well as an offset. ; This is declared in C as 'extern void gdt_flush();' global _gdt_flush ; Allows the C code to link to this extern _gp ; Says that '_gp' is in another file _gdt_flush: lgdt [_gp] ; Load the GDT with our '_gp' which is a special pointer mov ax, 0x10 ; 0x10 is the offset in the GDT to our data segment mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax jmp 0x08:flush2 ; 0x08 is the offset to our code segment: Far jump! flush2: ret ; Returns back to the C code!

但是,到目前为止,我的汇编语法有所不同,这是我在boot.s文件中所拥有的一部分.

However, my assembly syntax is different here is what I have so far as part of my boot.s file.

.global gdt_flush /*Allows the C code to link to this*/ .extern gp /*Says that '_gp' is in another file*/ _gdt_flush: lgdt gp /*; Load the GDT with our '_gp' which is a special pointer*/ mov %ax, 0x10 /* ; 0x10 is the offset in the GDT to our data segment*/ mov %ds, %ax mov %es, %ax mov %fs, %ax mov %gs, %ax mov %ss, %ax jmp flush2 /*; 0x08 is the offset to our code segment: Far jump!*/ flush2: ret /*; Returns back to the C code!*/

我的问题是如何将该指令的语法转换为我正在使用的格式?

My question is how do I translate the syntax of this instruction into the format I am using?

他的:jmp 0x08:flush2 ; 0x08 is the offset to our code segment: Far jump!

矿井:(long l?)jmp ????flush2 /*; 0x08 is the offset to our code segment: Far jump!*/

推荐答案

一些事情.远距离跳伞的AT& T语法是:

A few things. The AT&T syntax for a far jump is:

jmp $0x08,$flush2

在这种情况下,标签前面必须带有$.像0x08这样的立即值也需要$.这行代码没有按照您的想象做:

The label in this case needs to be preceded by a $. Immediate values like 0x08 also need a $. This line doesn't do what you think it does:

mov %ax, 0x10

关于AT& T语法的重要事项是,与Intel语法不同,操作数是相反的.源操作数是第一个,目标操作是后一个.其次,x86/x86-64上AT& T语法中的立即值必须在它们前面加上$符号,否则它们实际上被视为内存操作数.您的指令实际上将 AX 的16位内容移到了内存地址0x00000010上,这不是您想要的.您想要的是:

Important thing about AT&T syntax is that unlike Intel Syntax the operands are reversed. Source operand is first and destination operation is after. Secondly, immediate values in AT&T syntax on x86/x86-64 need to have a $ sign prepended to them or they are actually treated as a memory operand. Your instruction actually moved the 16-bit contents of AX to the memory address 0x00000010 which is not what you intended. What you wanted was:

mov $0x10, %ax

这会将立即值0x10移动到 AX .操作数取反的问题也适用于您的所有行,例如:

This moves the immediate value 0x10 to AX. The problem with operands being reversed also applies to all your lines like:

mov %ds, %ax

应该是:

mov %ax, %ds

我通常更喜欢调用您的函数load_gdt.我通常喜欢通过以下代码传递段值(CS和DS)和GDTR的地址:

I usually prefer calling your function load_gdt. I'm usually a fan of passing the segment values (CS and DS) and the address of the GDTR with code like:

load_gdt: mov 4(%esp), %edx # EDX is 1st argument - GDT record pointer mov 8(%esp), %eax # EAX is 2nd argument - Data Selector lgdt (%edx) # Load GDT with GDT record pointer passed as 1st argument mov %eax, %ds # Reload all the data descriptors with Data selector (2nd arg) mov %eax, %es mov %eax, %gs mov %eax, %fs mov %eax, %ss pushl 12(%esp) # Create FAR pointer on stack using Code selector (3rd argument) push $.setcs # Offset of FAR JMP will be setcs label below ljmp *(%esp) # Do the FAR JMP to next instruction to set CS with Code selector, # and set the EIP (instruction pointer) to offset of setcs .setcs: add $8, %esp # Restore stack (remove 2 DWORD values we put on stack to # create FAR Pointer) ret

C 原型如下所示:

void load_gdt(struct gdt_ptr *gdt_ptr, unsigned int data_sel, unsigned int code_sel);

如果要将GNU汇编器与Intel语法的变体一起使用,则可以尝试将此指令添加到所有汇编文件的顶部:

If you want to use GNU assembler with a variant of Intel Syntax you could try adding this directive to the top of all your assembly files:

.intel_syntax noprefix

更多推荐

程序集使用不同的语法执行带偏移的跳远

本文发布于:2023-11-08 09:34:55,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1569015.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:跳远   语法   程序

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!