【问题标题】:Why is my assembly program not working?为什么我的汇编程序不起作用?
【发布时间】:2013-10-01 09:02:21
【问题描述】:

我对组装完全陌生,现在我正在使用 X86 组装。我正在使用 NASM,现在我的代码没有编译。我从一本书中得到它,基本上该代码适用于字符串:

; This program demonstrates the string-handling procedures in
; the book's link library.
INCLUDE Irvine32.inc
.data
string_1 BYTE "abcde////",0
string_2 BYTE "ABCDE",0
msg0 BYTE "string_1 in upper case: ",0
msg1 BYTE "string1 and string2 are equal",0
msg2 BYTE "string_1 is less than string_2",0
msg3 BYTE "string_2 is less than string_1",0
msg4 BYTE "Length of string_2 is ",0
msg5 BYTE "string_1 after trimming: ",0
.code
main PROC
call trim_string
call upper_case
call compare_strings
call print_length
exit
main ENDP
trim_string PROC
; Remove trailing characters from string_1.
INVOKE Str_trim, ADDR string_1, '/'
mov edx,OFFSET msg5
call WriteString
mov edx,OFFSET string_1
call WriteString
call Crlf
ret
trim_string ENDP
upper_case PROC
; Convert string_1 to upper case.
mov edx,OFFSET msg0
call WriteString
INVOKE Str_ucase, ADDR string_1
mov edx,OFFSET string_1
call WriteString
call Crlf
ret
upper_case ENDP
compare_strings PROC
; Compare string_1 to string_2.
INVOKE Str_compare, ADDR string_1, ADDR string_2
.IF ZERO?
mov edx,OFFSET msg1
.ELSEIF CARRY?
mov edx,OFFSET msg2 ; string 1 is less than...
.ELSE
mov edx,OFFSET msg3 ; string 2 is less than...
.ENDIF
call WriteString
call Crlf
ret
compare_strings ENDP
print_length PROC
; Display the length of string_2.
mov edx,OFFSET msg4
call WriteString
INVOKE Str_length, ADDR string_2
call WriteDec
call Crlf
ret
print_leng

th ENDP
END main

就像我说我正在使用 NASM,所以这可能是问题,但它应该仍然可以工作,但是当我使用 nasm -f win32 other.asm -o other.o 编译它时,它会出现大量错误,其中大部分是预期的解析器指令。我使用的是 Windows 8 64 位,但它没有理由不能运行 32 位程序 - 如果我错了,请纠正我。 MASM 编译器的问题在于它说我需要精确的 Visual C++ Express 2005 (PRECISELY 2005) 才能下载,否则它不会下载。我怎样才能让这个程序与我将来可能编写的其他程序一起工作 - 我确实记得将 nasm 汇编器放入我的 C 编译器的 bin 文件中。就像我说的我很新,不管你信不信,这本书实际上并没有告诉你如何运行这个程序。还有一种方法可以在没有 VS 2005(我似乎无论如何都找不到)或该仪表的任何 VS 的情况下下载 masm

其他程序(在 ASM 中)似乎也无法在其上运行。我很确定这是 Windows 版本,否则一开始就不会下载。

【问题讨论】:

  • 如果您要从一个汇编器 (MASM) 转移到一个完全不同的汇编器 (NASM),不,它不会“仍然工作”。汇编器指令的语法是不同的。 “指令预期”错误意味着它遇到的任何东西都不是有效的 NASM 指令。你需要转换。例如,在nasm 中,通过%include 指令包含一个文件,而不是INCLUDE(注意百分号的存在)。您可以逐步检查每个解析器错误并挑选出必须更改的指令作为起点。
  • @mbratch 就像我说的那样,我真的不知道任何程序集,我只是想在开始编写程序之前让它全部启动并运行。因为我想跟着我的书,我可以让 NASM 去处理这个 INCLUDE 指令,或者我可以下载另一个汇编器 - 我知道 MASM,但由于上述原因我无法下载
  • 您可以在这里查看:left404.com/2011/01/04/…。我只是通过谷歌搜索“将masm转换为nasm”找到了这一点。 MASM 可能只对那些已经拥有 VS 的人免费授权。
  • 问题不在于你在使用 Nasm,而在于你给它提供了 Masm 代码。您可能想要的可以在masm32.com 找到。还有其他选择......但初学者不需要任何“额外”的复杂性!使用 Masm 没有害处 - 事后洗手! :)
  • @Kenny_007,Frank 指向您的站点,包括所有 MASM 工具 - ml、link、rc 等......所以,是的,它是真正的“东西”。我已经使用“SDK”很多年了。

标签: assembly nasm masm irvine32


【解决方案1】:

为什么我的汇编程序不工作?

因为您正在尝试使用 NASM 以 MASM 语法编译汇编代码。

选项 1:获取 MASM
不要试图将 MASM 代码放入 NASM。
这是行不通的,因为每个汇编程序都有自己的语法。
(是的,我同意这搞砸了)

根据@Frank 的建议从http://www.masm32.com/masmdl.htm下载masm
请注意,SDK(软件开发工具包)是实际的东西,包含编译代码所需的所有工具。
masm 安装程序通过重新编译开发工具来重建它们。这有点不寻常,但它确实确保了编译代码所需的所有工具都存在并且可以正常工作。

选项 2:使用 NASM 源代码示例
见:https://www.google.co.za/search?q=sample+nasm+programs&ie=utf-8&oe=utf-8&rls=org.mozilla:nl:official&client=firefox-a&gws_rd=cr&ei=uPNgUp-wBIqihgf45oDwCQ

选项 3:了解 MASM 和 NASM 之间的区别
The nasm manual 有一节介绍与 masm 的区别:http://www.nasm.us/doc/nasmdoc2.html#section-2.2
这也可能有帮助:http://left404.com/2011/01/04/converting-x86-assembly-from-masm-to-nasm-3/

选项 4:获取自动翻译器
幸运的是,有自动翻译器可以将 MASM 代码转换为 NASM。
这是一个:http://www.devoresoftware.com/nomyso/
请注意,这个特定的需要perl

【讨论】:

    【解决方案2】:

    使用以下代码:

    ; String Library Demo   (StringDemo.asm)
    
    ; This program demonstrates the string-handling procedures in 
    ; the book's link library.
    
    INCLUDE Irvine32.inc
    
    .data
    string_1 BYTE "abcde////",0
    string_2 BYTE "ABCDE",0
    msg0     BYTE "string_1 in upper case: ",0
    msg1     BYTE "string1 and string2 are equal",0
    msg2     BYTE "string_1 is less than string_2",0
    msg3     BYTE "string_2 is less than string_1",0
    msg4     BYTE "Length of string_2 is ",0
    msg5     BYTE "string_1 after trimming: ",0
    
    .code
    main PROC
    
        call    trim_string
        call    upper_case
        call    compare_strings
        call    print_length
    
        exit
    main ENDP
    
    trim_string PROC
    ; Remove trailing characters from string_1.
    
        INVOKE Str_trim, ADDR string_1,'/'
        mov     edx,OFFSET msg5
        call    WriteString
        mov     edx,OFFSET string_1
        call    WriteString
        call    Crlf
    
        ret
    trim_string ENDP
    
    upper_case PROC
    ; Convert string_1 to upper case.
    
        mov     edx,OFFSET msg0
        call    WriteString
        INVOKE  Str_ucase, ADDR string_1
        mov     edx,OFFSET string_1
        call    WriteString
        call    Crlf
    
        ret
    upper_case ENDP
    
    compare_strings PROC
    ; Compare string_1 to string_2.
    
        INVOKE Str_compare, ADDR string_1, ADDR string_2
        .IF ZERO?
        mov edx,OFFSET msg1
        .ELSEIF CARRY?
        mov edx,OFFSET msg2     ; string 1 is less than...
        .ELSE
        mov edx,OFFSET msg3     ; string 2 is less than...
        .ENDIF
        call    WriteString
        call    Crlf
    
        ret
    compare_strings  ENDP
    
    print_length PROC
    ; Display the length of string_2.
    
        mov     edx,OFFSET msg4
        call    WriteString
        INVOKE  Str_length, ADDR string_2
        call    WriteDec
        call    Crlf
    
        ret
    print_length ENDP
    
    END main
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多