将16位DOS x86程序集移植到32位Linux x86程序集

编程入门 行业动态 更新时间:2024-10-27 17:18:45
本文介绍了将16位DOS x86程序集移植到32位Linux x86程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我在80836 DOS程序集中找到了我想使用AT& T语法移植到32位Linux程序集的代码.

I found code in 80836 DOS assembly that I'd like to port to 32-bit Linux assembly, using AT&T syntax.

我发现了一个网站,该网站解释了一些差异,但仅与寄存器有关.例如:

I found site that explains some differences but only about registers. EX:

  • cmp al,'A'-> cmp'A',%al
  • 因此我在转换以下代码时遇到问题:

    So I got problems converting following code:

    input: mov ah, 00h int 16h cmp ah, 1ch je exit sub al, 30h sub al, 37h sub al, 57h mov ah, 02h mov dl, al int 21h mov dl, 20h int 21h exit: int 20h

    我正在转换此代码

    我认为:

  • sub al,57h ---> sub $ 0x57,%al和ETC(不确定)
  • 最糟糕的问题是中断,因为在AT& T汇编中,就像:

    The worst problem is with interrupts since in AT&T assembly it's like:

    SYSCALL = 0X80 SYSEXIT = 1 EXIT_SUCCESS = 0 SYSREAD = 3 SYSWRITE = 4 STDIN = 0 STDOUT = 1

    在DOS16中16h?20小时?21小时?哦,伙计,甚至int 20h仍然充当中断和值(mov dl,20h)?如此混乱.

    And in DOS16, 16h? 20h? 21h? oh man, and even then int 20h acts as interrupt and as value (mov dl, 20h)? so confusing.

    有人可以帮我吗?

    @EDIT我像这样转换它,但是出现了段错误错误.我几乎可以肯定这是关于中断的.

    @EDIT I converted it like this, but I got segmentation fault error. I am almost sure it's about interrupts..

    .data .text .global _start _start: input: movb $0x0,%ah int $0x16 cmpb $0x1c,%ah je exit number: cmpb $'0', %al jb input cmpb $'9', %al ja uppercase subb $0x30,%al call process jmp input uppercase: cmpb $'A', %al jb input cmpb $'F', %al ja lowercase subb $0x37,%al call process jmp input lowercase: cmpb $'a', %al jb input cmpb $'f', %al ja input subb $0x57,%al call process jmp input loop input process: movb $4,%ch movb $3,%cl movb %al,%bl convert: movb %bl,%al rorb %cl,%al andb $01,%al addb $0x30,%al movb $0x2,%ah movb %al,%dl int $0x21 decb %cl decb %ch jnz convert movb $0x20,%dl int $0x21 ret exit: int $0x20

    有人吗?

    推荐答案

    次要问题

    代码转换"的主要问题可能是您似乎将一些概念与"80836汇编"和"at& t"这两个词并没有真正应用.

    Minor Problem

    Probably the main problem of your code "conversion" is that you seem to connect some ideas with the terms "80836 assembly" and "at&t" that don't really apply.

    尽管这可能只是命名约定的问题,但"strong"和"at& t语法"之间并没有"80386程序集"与"at& T语法"的区别,两者都是两者可以使用intel语法和at& t语法来描述x86汇编代码.

    Although this might just be a matter of naming conventions there is no "80386 assembly" vs. "at&t" difference but a "intel" vs. "at&T syntax" difference as both intel syntax and at&t syntax can be used to describe x86 assembly code.

    如果您使用的是GNU汇编器(我不知道其他使用AT& T语法而不是intel的x86汇编器),您可能只想使用 .intel_syntax 并保持使用的intel语法而是在您的参考资料中.

    If you are using GNU assembler (I don't know any other x86 assembler using AT&T syntax instead of intel) you might just want to use .intel_syntax and stay with the intel syntax used in your reference material instead.

    .intel_syntax noprefix ; your code in intel syntax here .att_syntax prefix ; code in at&t syntax here

    如果要在实模式下使用它,请不要忘记切换到16位模式. .code16 .

    Don't forget to switch to 16-bit mode.code16 if you intend to use it in real mode.

    这个问题更大的问题似乎是,您不仅在尝试将代码从[in-syntax]转换为[at& t-syntax],而且要转换端口它到一个.另一个寻址模式和b.另一个操作系统.

    The far the bigger problem with your question seems to be that you are not only trying to transform the code from using "intel-syntax" to using "at&t-syntax" but rather to port it to a. another addressing mode and b. another operating system.

    尤其是您有关中断调用约定的问题使我想到一个假设,您正在尝试将16位DOS代码移植到在LINUX机器上运行的某种32位代码上.

    Especially your question about interrupt calling conventions leads me to the assumption you are trying to port 16-bit DOS code to some kind of 32-bit code running on a LINUX machine.

    仅通过替换数字就不可能重用"给定的代码来执行系统调用,因为其中涉及不同的调用约定.

    Just "reusing" the given code to perform system calls won't be possible by simply replacing numbers as there a different calling conventions involved.

    您可能会尝试修改代码的方法包括使用syscall read而不是BIOS中断来从stdin读取

    Things you might try to fix your code include using syscall read instead of BIOS interrupt to read from stdin

    storage: .ascii " " # ... movl $3, %eax # syscall number # (check syscall.h to see if it's 3 on your system) movl $0, %ebx # file descriptor (0 designating stdin) movl $storage, %ecx movl $1, %edx # number of chars to read int $0x80

    除了使用类似的东西之外,还必须修复利用DOS syscall机制int 0x21的代码

    Code utilizing DOS syscall mechanism int 0x21 would have to be fixed in addition using something like

    movl $4, %eax # syscall number write movl $0, %ebx # file descriptor (1 designating stdout) movl $storage, %ecx movl $1, %edx # number of chars to write int $0x80

    最后一步应该是修复出口syscall:

    The last step should be fixing the exit syscall:

    movl $1, %eax # syscall number exit movl $0, %ebx # it doesn't hurt to set a reasonable exit code here. int $0x80

    请求的文档来源

    • 关于DOS系统调用,请参见 en.wikipedia/Wiki/MS-DOS_API 应该有助于了解示例代码中使用的 int 0x20 和 int 0x21 .

      Requested Documentation Source

      • Regarding DOS syscalls taking a look at en.wikipedia/wiki/MS-DOS_API should help to understand what int 0x20 and int 0x21 are used for in your example code.

        为BIOS中断而抢劫也是Wikipedia的朋友: en.wikipedia/wiki/Bios_interrupt 应该回答您的问题.

        Seraching for BIOS interrupt also wikipedia is your friend: en.wikipedia/wiki/Bios_interrupt should answer your question.

        在您的情况下,它是 int 0x16 和 ah 中的 0 -因此:读取字符.

        in your case it is int 0x16 with 0 in ah - thus: read character.

    更多推荐

    将16位DOS x86程序集移植到32位Linux x86程序集

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

    发布评论

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

    >www.elefans.com

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