- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
英语不是我的母语;请原谅输入错误,我将在此处显示的代码是一项作业。
我真的需要了解发生了什么事。我在 DosBox 0.74 和 TASM 汇编器中使用 Intel 8086 语法。
当我必须除以 2 时,代码的问题出在三角形的面积上。注意:程序总是从键盘读取 1 位数字。看代码(这里的一个用户建议显示我的所有代码而不是部分显示,我认为有点长,但我认为他是对的,更具可读性)[注:我编辑了这个问题,只编辑了部分有问题的代码在这里,我花了一些时间将注释和消息翻译成英文,这有点长,我没有太多时间全部翻译]:
;Segmento de Datos
DATA SEGMENT 'DATA'
LADO1 DB ? ;con el ? se indica que la variable no tiene nada
LADO2 DB ?
LADO3 DB ?
BASE DB ?
ALTURA DB ?
COUNTER DB 0 ;contador para muestra de mensajes
;mensajes ESPECIFICOS
MSG_PRESENTACION DB 10,13,"Este programa calcula los perimetros y areas de algunas figuras geometricas $"
;triangulo
MSG_DIMENSIONES_TRIANGULO DB 10,13,10,13,"Ingrese las dimensiones del triangulo (considere el lado 2 como la BASE)$"
MSG_PERIMETRO_TRIANGULO DB 10,13,"El perimetro del triangulo es: $"
MSG_AREA_TRIANGULO DB 10,13,"El area del triangulo es: $"
;triangulo
;cuadrado
MSG_DIMENSIONES_CUADRADO DB 10,13,10,13,"Ingrese las dimensiones del cuadrado$"
MSG_PERIMETRO_CUADRADO DB 10,13,"El perimetro del cuadrado es: $"
MSG_AREA_CUADRADO DB 10,13,"El area del cuadrado es: $"
;cuadrado
;rectangulo
MSG_DIMENSIONES_RECTANGULO DB 10,13,10,13,"Ingrese las dimensiones del rectangulo$"
MSG_PERIMETRO_RECTANGULO DB 10,13,"El perimetro del rectangulo es: $"
MSG_AREA_RECTANGULO DB 10,13,"El area del rectangulo es: $"
;rectangulo
;otros mensajes GENERALES
MSG_ALTURA DB 10,13,"Introduzca la altura: $" ;sirve para solicitar la altura de varias figuras
MSG_BASE DB 10,13,"Introduzca la base: $"
MSG_LADO DB 10,13,"Ingrese el lado $"
MSG_PUNTO DB ": $" ;sirve para colocar 2 puntos luego del lado
MSG_PRUEBA DB 10,13,10,13,"El valor de prueba es: $"
DATA ENDS
;Segmento de codigo
CODE SEGMENT 'CODE'
ASSUME DS:DATA,CS:CODE ;se le indica al Assembler que DATA es el nombre dado al DATA SEGMENT, y CODE el nombre de CODE SEGMENT
MAIN PROC ;incia el inicio del segmento de codigo
MOV AX,DATA ;hacer disponible/accesible el contenido del DATA SEGMENT al CODE SEGMENT
MOV DS,AX ;inicializar el data segment, debido a limitacion de MOV, se hace con la ayuda de AX
LEA DX,MSG_PRESENTACION ;Mensaje de presentacion / introduccion
CALL printString
;triangulo********
LEA DX,MSG_DIMENSIONES_TRIANGULO ;carga a DX el mensaje 1 (Se le dice al usuario que introduzca los datos del triangulo)
CALL printString
;SOLICITUD DE DATOS ----//----
LEA DX,MSG_ALTURA ;indica al usuario que introduzca la altura del triangulo
CALL printString
CALL readNumber ;se lee del teclado la entrada del usuario mediante este procedimiento (1 digito)
MOV ALTURA,AL
LEA DX,MSG_LADO ;se le dice al usuario que introduzca el lado 1
CALL printString
CALL numberInMessage ;muestra el numero 1 despues del mensaje anterior y DOS PUNTOS para introducccion de datos (solo con fines de formato)
CALL readNumber
MOV LADO1,AL ;mueve valor capturado a la variable
LEA DX,MSG_LADO ;se le dice al usuario que introduzca el lado 2 (la base)
CALL printString
CALL numberInMessage ;muestra el numero 2 despues del mensade de LADO
CALL readNumber
MOV LADO2,AL ;mueve valor capturado a la variable
LEA DX,MSG_LADO ;se le dice al usuario que introduzca el lado 3
CALL printString
CALL numberInMessage ;muestra el numero 3
CALL readNumber
MOV LADO3,AL ;mueve valor capturado a la variable
;PERIMETRO DE TRIANGULO ----//----
ADD AL,LADO2 ;SUMA LADO3(AL) CON CON LADO2 y lo guarda en AL
ADD AL,LADO1 ;SUMA LO ANTERIOR CON LADO1
MOV AH,0 ;borra basura de AH
AAA ;significa ASCII Adjust after Addition
MOV BX,AX ;los registros AH y AL se usan una y otra vez, por tanto para evitar perder sus datos se mueven a BH y BL, esto se hace moviendo AX a BX
LEA DX,MSG_PERIMETRO_TRIANGULO ;lee la direccion efectiva de memoria del mensaje (resultado de la suma) y la carga en DX
CALL printString ;printDigits usa BX para la impresion de los datos
CALL printDigits ;imprime resultado
;AREA DE TRIANGULO ----//----
MOV AL,LADO2 ;multiplicar la base (LADO2) por la altura
MUL ALTURA
AAM
MOV BL,2
AAD
DIV BL
MOV BX,AX
LEA DX,MSG_AREA_TRIANGULO ;mensaje que indica la impresion del area del triangulo
CALL printString
CALL printDigits ;imprime numeros del area del triangulo
;FIN triangulo********
;cuadrado********
LEA DX,MSG_DIMENSIONES_CUADRADO
CALL printString
;SOLICITUD DE DATOS ----//----
LEA DX,MSG_LADO
CALL printString
LEA DX,MSG_PUNTO ;solo con fines de formato, muestra los 2 puntos antes la entrada del usuario
CALL printString
CALL readNumber ;recordemos que la lectura se almacena en AL
MOV LADO1,AL
;PERIMETRO DEL CUADRADO ----//----
MOV AH,4 ;MUL no acepta valores constantes como argumentos, por tanto se mueve a un registro
MUL AH ;multiplicamos la entrada del usuario por 4 y se almacena en AL
MOV AH,0 ;se limpia basura de AH
AAM ;ya explicado, se iran reduciendo comentarios debido a esto, no se omitiran valores y/o situaciones especificas y necesarias para entender
MOV BX,AX ;se mueve porque se trabaja mucho con AX, y evitamos posible perdida de los datos
LEA DX,MSG_PERIMETRO_CUADRADO
CALL printString
CALL printDigits ;imprime lo que esta en BX
;AREA DEL CUADRADO ----//----
MOV AL,LADO1
MUL AL ;multiplicamos la entrada del usuario por el mismo, ya que se desea elevar al cuadrado
MOV AH,0 ;se limpia basura de AH
AAM
MOV BX,AX ;se mueve porque se trabaja mucho con AX, y evitamos posible perdida de los datos
LEA DX,MSG_AREA_CUADRADO
CALL printString
CALL printDigits ;imprime lo que esta en BX
;FIN cuadrado********
;rectangulo********
LEA DX,MSG_DIMENSIONES_RECTANGULO
CALL printString
;SOLICITUD DE DATOS ----//----
LEA DX,MSG_BASE
CALL printString
CALL readNumber
MOV BASE,AL
LEA DX,MSG_ALTURA
CALL printString
CALL readNumber
MOV ALTURA,AL
;PERIMETRO DEL RECTANGULO----//----
MOV AH,2 ;no se puede usar MUL con una consatnte, por tanto se mueve a un registro
MUL AH ;AL contiene la ALTURA, y se multiplica por 2
MOV AH,0 ;se limpia la basura
AAM
MOV BX,AX ;se guarda en otro registro para evitar perdida de datos
MOV AL,BASE
MOV AH,2 ;mismo procedimiento que arriba para multiplicar por un numero constante
MUL AH
MOV AH,0
AAM
ADD BX,AX ;se suma el primer resultado (guardado en BX), con lo ultimo conseguido (guardo en AX), el resultado queda e BX
AAA
LEA DX,MSG_PERIMETRO_RECTANGULO
CALL printString
CALL printDigits
;AREA DEL RECTANGULO ----//----
MOV AL,BASE
MUL ALTURA
MOV AH,0
AAM
MOV BX,AX
LEA DX,MSG_AREA_RECTANGULO
CALL printString
CALL printDigits
;FIN rectangulo********
MOV AH,4CH ;EXIT, termina el programa
INT 21H ;ejecuta la interrupcion
MAIN ENDP ;acaba la rutina principal
;PROCEDIMIENTOS -----------------------------------------------------------------------------------------------------------------------------
printDigits PROC
ADD BX,3030H ;como AH & AL (BH & BL) estan en BCD, se le suman 30 para obtener el valor en ASCII
;primer digito
MOV AH,2 ;se le indica a la interrupcion que haremos una impresion de un CARACTER
MOV DL,BH ;como BH contiene el primer digito, se imprime este primero pasando el valor a DL
INT 21H ;se llama a la interrupcion, que ejecuta lo especificado por AH, tomando como entrada DL
;segundo digito
MOV AH,2 ;nuevamente se le indica una impresion (STANDARD OUTPUT)
MOV DL,BL ;esta vez se pasa el segundo digito
INT 21H ;y se imprime
RET
printDigits ENDP
printString PROC
MOV AH,9 ;se pasa a AH el 9 para indicar que se hara una salida a STANDARD OUTPUT
INT 21H ;interrupcion del DOS, que funciona con el valor del registro AH, el 9 indica STANDARD OUTPUT
RET
printString ENDP
readNumber PROC
MOV AH,1 ;1 en AH indica STANDARD INPUT
INT 21H ;Se usa la interrupcion para tomar entrada del teclado (por instruccion 1 en AH), se retorna lectura a AL
SUB AL,30H ;se convierte de ASCII a numero normal para realizar las operaciones deseadas, el 30 es porque se recibe el numero en BCD desempacado
RET
readNumber ENDP
numberInMessage PROC
ADD COUNTER,1 ;añade 1 a al contador, para nuevos usos es necesario limpiar COUNTER antes de la llamada
MOV BL,COUNTER ;se mueve porque se desea imprimir el contador, y printDigits trabaja con BX
MOV BH,0
CALL printDigits
LEA DX,MSG_PUNTO ;contiene el mensaje de los dos puntos para formato solamente
CALL printString
RET
numberInMessage ENDP
CODE ENDS ;final del segmento de codigo
END MAIN
注意:“AREA DE TRANGULO”是唯一有问题的部分。
这不适用于所有数字(那些输出为 2 位数字的数字),我认为这里的问题是 AAM 和 AAD 指令,AAD 要求 AX 有一个 2 位数字打包的 BCD 数字,所以我决定删除 AAM指导,这也不起作用。所以我想知道我在这里缺少什么,这样做得到的输出是(使用 5 和 6,5*6=30/2=15):
The area of the triangle is: 0?
我认为 AAD 指令是问题的一部分,如果我使用其他数字,例如 4 和 4,这将是输出:
The area of the triangle is: 08
所以,我决定删除 AAD 指令,但行为是一样的,你能告诉我为什么吗?
预先感谢您的时间和帮助! (如果您认为在我的代码中还有另一种方法可以做某事,并且出于任何原因更好,请告诉我,我想学习)
最佳答案
您需要了解 AAM 和 AAD 的实际用途。 AAM 指令将 AX 中 00-99 范围内的二进制数转换为 AH 和 AL 中的两个未压缩的十进制数字。 AAD 执行此操作的相反操作,它将 AH 和 AL 中的两个解包十进制数字转换为 AX 中 00-99 范围内的二进制数。这就是它们所做的全部事情,尽管它们的名字表明它们只能分别在乘法之后和除法之前使用。
用于计算三角形面积的代码以 0 到 9 范围内的两个独立的二进制数开始,然后将它们相乘得到 0 到 81 范围内的二进制数。然后使用 AAM 来计算将 AX 中的二进制结果转换为 AH 和 AL 中的两个解包数字。然后,它几乎立即使用 AAD 将 AH 和 AL 中的解包数字转换回 AX 中的二进制数。
希望您能够看到,先使用 AAM 再使用 AAD 并不会产生任何有用的效果。您从 AX 中的二进制数开始,最终在 AX 中得到相同的二进制数。您要做的是将两个维度相乘,然后除以二,最后将结果转换为单独的数字以进行打印。所以你应该做的是这样的:
MOV AL,LADO2
MUL ALTURA
MOV BL,2
DIV BL
AAM
请注意,AAM 不遵循乘法指令并不重要。不管怎样,它都会进行相同的转换。
请注意,您可以利用二进制右移与无符号除以二相同的事实来简化此代码:
MOV AL,LADO2
MUL ALTURA
SHR AX, 1
AAM
最后,我要指出的是,现代代码不使用 AAM 和 AAD 等指令,因为它们比使用更通用指令的等效操作要慢。
关于assembly - 我试图在 AAM 指令之后使用 AX 中存储的值将其除以 2,为什么它不适用于 2 位数字输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40575942/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!