【问题标题】:compare number and variable in assemblyx86比较汇编x86中的数字和变量
【发布时间】:2016-06-25 11:56:19
【问题描述】:

此代码逐个字符地从输入文件中读取数据,然后写入另一个文件。 一旦找到值等于 3 的字符,它应该停止读写。 我说应该是因为程序一旦找到等于 3 的值就不会停止,而是继续读取直到文件结束。

输入文件如:2 4 5 3 1 8

我的代码是:

.section .data

  varInputHandle: .long 100
  varOutputHandle: .long 100
  varExitCode: .long 1
  cont: .long 1
.section .bss
  .lcomm varBuffer, 1        

.section  .text              # declaring our .text segment
  .globl _start              # telling where program execution should start

_start:

    popl %eax       # Get the number of arguments
    popl %ebx       # Get the program name

    # open input file first 
    popl %ebx       # Get the first actual argument - file to read
    movl $5, %eax       # open
    movl $0, %ecx       # read-only mode
    int $0x80
    movl %eax, varInputHandle   #store input file handle to memory

    #open output file, make it writable, create if not exists
    popl %ebx           # Get the second actual argument - file to write
    movl $5, %eax       # open 
    movl $0101, %ecx    # create flag + write only access (if google is telling me truth)
    movl $0666, %edx    #permissions for out file as rw-rw-rw-
    int $0x80
        movl %eax, varOutputHandle #store output file handle to memory

contToZero:
movl $0, cont
processingLoop:
    incb cont
    #read single char to varBuffer
    movl $3, %eax
    movl varInputHandle, %ebx
    movl $varBuffer, %ecx
    movl $1, %edx
    int $0x80

    #if no char was read (EOF?), jmp finishProcessing
    cmpl $0, %eax
    jz finishProcessing # looks like total success, finish cleanly

    cmpl $3, varBuffer   // this instruction is never true, don't know why
    je exitToOs
    #write it
    movl $4, %eax       
    movl varOutputHandle, %ebx     # file_descriptor
    movl $varBuffer, %ecx  
    movl $1, %edx
    int $0x80

    # done, go for the next char
    goForTheNextChar:
    jmp processingLoop

finishProcessing:
    movl $0, varExitCode #everything went OK, set exit code to 0

exitToOs:
    movl varOutputHandle, %ebx     # file_descriptor
    movl varInputHandle, %ebx    
    movl $1, %eax
    movl varExitCode, %ebx
    int $0x80

closeFile:
    cmpl $-1, %ebx
    movl $6, %eax  #sys_close
    int $0x80

cmpl $3, varBuffer 似乎永远不会是真的,因此我无法跳转到 exitToOs。

【问题讨论】:

  • 您可以自己查看varBuffer 中的字节来调试它,例如在 gdb 中使用 x varBuffer。你会注意到它们是 ASCII 编码。
  • 另外,movl $0, cont / ... / incb cont 可能是一个错误。如果可能,请将cont 保存在寄存器中。 %esi%edi 似乎没有在您的代码中使用。
  • 我看到您确实对您的其他问题做出了回答,我很高兴。但是我看到您确实删掉了一些部分并更改了一些位,在某些情况下变得更糟,在某些情况下只是没有正确处理错误状态。如果您对这些省略的部分有特殊问题,欢迎您对有关它的原始问题发表评论,以便您完全理解它并使代码以适当的方式“工作”,不仅在某些情况下而且完全靠运气。最后也得到调试器并学习如何使用它。当我学习 Z80 ASM 并且我不得不在纸上调试时,我会为调试器付出代价。

标签: linux assembly x86 att


【解决方案1】:

在您的代码中:

 cmpl $3, varBuffer

这永远不可能,因为您的文件中没有二进制数据。

当您逐个字符读取时,您正在读取 ASCII 值。为了正确进行这种比较,您必须做以下两件事之一:

  1. 将读取的字符从 ASCII 转换为十进制
  2. 将读取的值与 ASCII 值进行比较

由于您依靠 $0 来识别您何时读取了零字节,因此我建议您采用(更简单的)方法来检查您想要查找的 ASCII 值。在您的情况下,这将是:

 cmpb $'3', varBuffer     # Compare character to 0x33 / 51 / "3"

【讨论】:

  • 我不知道这个(AT&T 语法)汇编器,但也可以写:cmpl '3', varBuffer,或者那不是有效的语法?与 IMO 的 '3' 进行比较会更清楚。
  • 不应该是$0x33$33h 而不是$33?后者可能只有 33(十进制)。
  • @RudyVelthuis:是的,在 AT&T 语法中你可以写成cmpl $'3', dst。或者为了演示对更复杂语法的毫无意义的使用,cmpl $( 3 + '0' ), dst。我刚刚测试过,$33h 没有组装。 Error: junk 'h' after expression
  • 感谢您的信息。在这种情况下,我更喜欢 $'3'。
  • 我猜 33h 是只有 Intel 的。
猜你喜欢
  • 2011-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多