在Assembly 8086

时间:2017-01-14 19:12:03

标签: assembly x86-16 dos

我试图在8086汇编中完成作业。但我似乎无法得到它。我知道我的代码是不正确的,我试图找到正确的方法和答案(人们告诉我它完全错误,就像从一开始就不是正确的道路)。

我在向量中找到最大数字时遇到问题。

.model small
.stack 100h
.data
  a db '5 ', '21 ', '4 ', '13 ', '2 ', '31 ', '22 ', '$' - the vector
  max db 0 - max variable
.code
  mov ax,@data
  mov ds,ax
  mov ah, 09h
  mov dx, offset a
  int 21h
  mov si,0 - setting the increment variable to 0
  jmp e1

e1: 
  mov bh,a[si]
  mov dh,a[si+1]
  cmp bh,dh - compare the 0 element to the 1 element
  jl e2
  inc si
  jmp e1

e2: 
  mov max,dh - if bh is less than dh, set max to dh value
  inc si
  cmp si, 6 - starting from 0, compare if the increment variable is at the end
  je e3
  jmp e1

e3:
  mov dx,offset max
  mov ah,09h
  int 21h
  mov ah,4ch
  int 21h
end

人们告诉我,我应该重新想象它,但我不知道如何做到这一点。他们说我的代码不起作用的原因是因为汇编将整个事物包含在撇号中,包括空间。我应该以某种方式使用ASCII表,这是一个痛苦的屁股。

1 个答案:

答案 0 :(得分:2)

我不清楚,使用ASCII是如何痛苦的,因为你的汇编程序知道ASCII,所以它正在为你做所有艰苦的工作。

如果不是,你将不得不定义“Hello world!”像这样:

hello_str    db     72, 101, 108, 108, 111, 32
             db     119, 111, 114, 108, 100, 33, 36

而不是方便的

hello_str    db     'Hello world!$'

您实际上可以执行sub al,'0'之类的操作,因此您无需记住'0'是值48,就像我从8位时代印在大脑中一样,因为那时我没有任何汇编程序,我不得不手工将我的代码从纸张汇编成机器代码字节,然后编写简短的BASIC程序,它确实用那些手工计算的值设置了内存。如果我搞砸了指令编码,那么执行完全不同的东西并且通常会使整个机器崩溃。你不知道,如果你认为ASCII是什么,PITA是什么。 :d

顺便说一句,即使你的代码中的高级逻辑是错误的,即使它在向量值方面的效果如你所愿,你也会得到错误的结果,例如:

vector:2,8,3,5,4,4将报告最大值5

如果你将vector放入单独的数据段,并用相同的值填充它(例如65536 x“5”),你将以无限循环结束。

首先在这样的评论中写下你的算法:

; load vector size
; if size is zero, end with "no data" result
  ; (jump separate branch of code with own exit)
; set temporary_max to first element of vector
; load index to point to second element of vector
; while (index within bounds of vector) do {
  ; compare vector element at index with temporary_max
  ; if element is greater, then temporary_max = element
  ; increment index and loop }
; print temporary_max as result
; exit to DOS

然后尝试用一些指令填充核心部分,比如“比较元素”和“索引”与“长度”,这样你就可以想到你的数据如何存储在内存中,它们的结构是什么,它们是什么bitsize,它们的编码是什么,以及可以使用哪些指令来操作它们。

如果您猜测核心部分,请检查您需要多少个寄存器,如果您只能完全适合CPU,或者您还需要一些局部变量或堆栈存储器,并分配CPU寄存器以具有固定功能对于大多数代码(如整个“find max”循环只能在读取向量元素时触摸内存,其他所有内容都可以适合寄存器)。将这些分配写入注释,在有任何寄存器冲突的地方做笔记,并且你必须通过额外的方式(推/弹出或局部变量)保留一些值。

然后尝试用真实指令填写每个评论部分,这次完全解决它。请尽量从一小部分开始,并在调试器中逐步验证它是否按预期工作(例如,假设前面有一些假mov register,test_value来模拟您在该部分中所期望的状态,因此您可以在调试器按预期工作。)

完成所有部件的填充和调试后,该程序应该可以运行。完成。

最后一件事......让我后悔甚至后悔自己也懒得和你分享这么多经验和知识......

你怎么能在你的来源中写一些像“e1:”这样的东西。

你是否急于再次敲击键盘10次?但是,为什么你突然有时间在这里发表整个问题?

您应该学习编程的第一件事是,您将阅读源代码多次,而不是写它。

在写作源代码时,没有必要采取捷径,如果他们使阅读更加困难,那将无法节省任何时间。每当你看到有更清晰的方法来重写你的源代码时,就去做吧。它可能需要几分钟,但如果结果更清晰/更短/更容易阅读源,它将在以后,当您将阅读它时多次付款(多次,在调试期间等)。

如果您认为e1:足够好,那么我建议您,根本不使用标签,只需将偏移直接写入代码,而不是je e3您可以写{ {1}}现在您甚至不需要在源代码中编写je $+4。获胜。