كيفية تحديد موقع متغير بشكل صحيح في أت & ر التجمع?
-
11-12-2019 - |
سؤال
أنا ممارسة لكتابة بوتستراب باستخدام التجمع (في أت و تي بناء الجملة ، و غنو/الغاز).يتم تجميع البرنامج الصغير وربطه ، ثم نسخه إلى القطاع الأول من القرص الظاهري.سوف بيوس تحميله في 0000:7c00
, ، وهنا تأتي المشكلة.ال call hello
سيتم ترجمتها من call 0010
إلى call 7c10
أثناء الجري.لكن ال movw $message, %as
لا يتم نقلهم.ال ax
لا يزال 0026
, ، ليس 7c26
.والنتيجة هي أنني لا يمكن أن تجعل من Hello World
على الشاشة.بدلا من ذلك ، بعض البيانات العشوائية في 0000:0026
سيتم عرضها على الشاشة.
كيف يمكنني جعلها صحيحة أثناء التمهيد?يجب أن أغير شفرة المصدر أسم باستخدام بعض التوجيهات?أم يجب أن أغير نص الرابط الخاص بي?
شكرا لك!
.text
.global _start
.code16
_start:
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
call hello
jmp .
.org 0x10
hello:
movw $message, %ax
movw %ax, %bp
movw $13, %cx
movw $0x1301, %ax
movw $0x000c, %bx
movb $0, %dl
int $0x10
ret
message:
.ascii "Hello, World!"
.org 0x01fe
.byte 0x55
.byte 0xaa
يمكنني استخدام تجميع وربط البرامج النصية التالية
as -o boot.o boot.s
//generate object code
ld -Ttext 0x0 -e _start -s -o boot.out boot.o
//relocate .text to 0x0
//entry is _start
objcopy -O binary -j .text boot.out boot
//copy .text section to boot
vboxmanage convertfromraw boot boot.vdi --format VDI
//create vdi for virtual box
المحلول
أرى أن المشكلة الرئيسية هي في الطريقة التي يتم تجميع التعليمات البرمجية الخاصة بك.
يجب أن تكون الخطوات الصحيحة لتشغيل الكود الخاص بك:
as boot.s -c -o boot.o
ld --oformat binary --Ttext 0x7C00 -o boot.bin boot.o
يرجى ملاحظة ، كما قال آخرون ، أن أنا تمرير --Ttext 0x7C00
المعلمة إلى ld
, ، لإجبارها على نقل التعليمات البرمجية الخاصة بك في هذا العنوان.
كاقتراح إضافي ، حاول هيكلة التعليمات البرمجية الخاصة بك مثل هذا:
.text
.global _start
.code16
_start:
jmp stage1_start
...
stage1_start:
<your bootloader here>
لاحظ أن هذا هو متناسق مع كيف يبدو رمز بيوس في محركات الأقراص الصلبة ، لأنه بعد 2 بايت (طول تعليمات القفزة الأولى) يجب وضع جدول وصف القرص.
بالإضافة إلى ذلك ، يمكنك إعادة بناء تعليماتك الأخيرة في المزيد as
- مثل بناء الجملة مثل هذا:
. = _start + 0x0200 - 2
.short 0x0AA55
حيث .
المتغير هو عداد الموقع.انظر إلى هذه الصفحة لمزيد من المعلومات حول كيفية عمل هذا العداد (في سياق ld
, ، ليس as
).
نأمل أن يساعد هذا!