所以,从一个单词数组开始,我必须创建一个数组来包含每个给定单词的数字,用基数10写成。
所以,如果我有
s DW 12345, 20778, 4596
结果应该是这个BYTE数组
t DB 1, 2, 3, 4, 5, 2, 0, 7, 7, 8, 4, 5, 9, 6
我被建议怎么做,我已经尝试过实现它,但我收到以下错误
对操作或指令的争论具有非法规模“
(关于“推al”和“pop al”行)
以下是我尝试实施的代码:
ASSUME cs:text_,ds:data_
data_ SEGMENT
s dw 12345, 20778, 4596
l equ $-sir
d db (l/2)*5 dup (?)
data_ ENDS
text_ SEGMENT
start:
mov ax, data_
mov ds, ax
mov es, ax
mov si, offset s
mov di, offset d
mov cx, l ;storing the length of s
mov dl, 10
mov ax, [si] ;storing the data of si into ax so that the division can be made
cld ;setting the direction flag
jmp loop1
cloop1:
div dl ;divide by 10 so we can get the remainder
push al ;ERROR LINE ;my plan was to store the value of al into the stack, so I can store the remainder into al
mov al, ah
stosb ;we add the remainder to the final line
pop al ;ERROR LINE ;my plan was to get the value of al from the stack and do the instruction once againq
loop cloop1
loop1: ;the role of this loop is to repeat the instruction as long as there are words left (similar to while instruction in C++)
cmp ax, 0
jg cloop1 ;if there are words left, the code keeps on being executed
loop loop1
mov ax, 4c00h
int 21h
text_ ENDS
end start
这是基于它的想法(用C ++表示):
nr=0;
while(x>0)
{c=x%10;
nr=nr+x*10;
x=x/10;
}
cout<<nr;
提前致谢并对任何错误表示歉意。关于我的问题的任何建议将不胜感激
答案 0 :(得分:1)
您不能将8位寄存器压入堆栈。在16位模式下,您只能推送和弹出16或32位寄存器。尝试将push al
和pop al
替换为push ax
和pop ax
。
答案 1 :(得分:1)
你的C循环是理智的,除了nr=nr+x*10;
我认为你转换回一个反转的十进制数字整数?这并不是一个在asm中考虑它的有用方法,因为你没有cout << nr
库功能。
通常的策略(特别是如果你只需要打印成一个字符串)是从一个指向缓冲区的 end 的指针开始并向前工作。 (例如dec di
/ ... / div / add dl, '0'
/ mov [di], dl
/ test ax,ax
/ jnz
)。有关x86-64版本,请参阅示例How do I print an integer in Assembly Level Programming without printf from the c library?。将数字转换循环移植到具有16位整数的x86-16是很简单的;我没有使用任何x86-64特定的东西。
一旦你的商变为0,你就退出循环;你完成了,你的印刷顺序是你的数字。数字来自当前指针(di
)到缓冲区末尾的任何位置。将其提供给打印字符串函数(我认为int 21h
具有其中之一)。
如果要将结果放在具有固定起始位置的数组中,则可以复制。但是如果你只需要在连续缓冲区中将所有数字作为整数,那么你就可以得到它。从为缓冲区分配的空间末尾的最后一个单词开始。当您获得单词中的所有数字时,请转到下一个单词(sub si,2
),但不要移动di
,因此下一个单词的数字是存储在高位地址字的数字之前。或者,如果您要针对代码大小进行优化,请使用lodsw
和stosb
。
当您完成源数组的最后一个单词时,di
指向数组数组的开头。
Push
在循环中生成然后pop
是处理div / mod算法生成最低有效第一顺序数字的另一种方法。但它需要一个单独的循环来弹出。正如@Fuz指出的那样,你必须推/弹整个16位寄存器。