首先,这是一项家庭作业。
我有一个循环获取两个数字的值分别,并join他们的第一个数字乘以10,并加上第二个数字得到一个整数。
我正在做这一切,并保存在我的AL寄存器,现在我想插入整数到一个数组,然后扫描该数组,并显示这些数字。
我如何插入vector和从vector读取?
Windows XP自动将数组初始化为零?
C ++ WINAPI共享内存数组的结构
如何在BASH中制作3D数组?
awk命令结果放入数组
带有bash for循环的SSH命令选项
我的arrays:
section .bss array resb 200
我的数字转换:
sub byte[digit_une],30h sub byte[digit_two],30h mov al,byte[digit_one] mov dl,10 ;dl = 10 mul dl ;al = ax = 10 * digit_one add al,byte[digit_two] ;al = al + digit_two = digit_one * 10 + digit_two
字符数组问题
copy_to_user包含数组(指针)的结构
比较多个数组列表的长度,find最长的一个
bash中的关联数组名称的数组
C shell:如何从一行标准input创build多个数组?
“阵列”,“矢量”等等,都是更高层次的概念。 机器有内存,可以用单个字节寻址,你用你的代码实现了什么样的逻辑,这取决于你。 但是你应该能够在两个层面上思考它,就像内存中的单个字节一样,每个字节都有自己的地址,并且完全理解你的代码逻辑,它将如何安排这些字节的使用以形成“一些东西”。
使用.bss扇区的定义,您可以定义一个符号/标签array ,它等于.bss段开始的内存地址。 然后你保留200字节的空间,所以你会添加任何其他(如另一个标签)将开始在地址.bss+200 。
比方说,将二进制文件加载到内存中并跳转到入口点后,.bss位于地址0x1000 。
然后
mov dword [array],0x12345678
将存储4个字节到地址0x1000 .. 0x1003存储器中,其中特定字节的值为78 56 34 12 (该dword值的小端分解)。
如果你要执行mov dword [array+199],0x12345678 ,那么你将在resb 200的最后一个正式保留字节中写入值0x78 ,剩下的3个字节将覆盖地址.bss + 200,.bss + 201和.bss + 202(可能会损坏一些其他数据,如果你将这些东西放在那里,或者崩溃你的应用程序,如果它将跨越内存页面边界,并且你处于可用内存的末尾)。
因为你想把N 字节的值存储到数组中,最简单的逻辑就是将第一个值存储在地址array+0 ,第二个array+1等等(对于双字值,最合理的方式是array+0,array+4,array+8,.... )。
即mov [array+0],al可以用来存储第一个值。 但是,如果您正在阅读某种循环中的输入,这不是很实际。 假设您想要从用户处读取至多200个值,或者值99会更快结束,那么您可以使用通过寄存器索引,如:
xor esi,esi ; rsi = index = 0 mov ecx,200 ; rcx = 200 (max inputs) input_loop: ; do input into AL = 0..99 integer (preserve RSI and RCX!) ... cmp al,99 je input_loop_terminate mov [array+rsi],al ; store the new value into array inc rsi ; ++index dec rcx ; --counter jnz input_loop ; loop until counter is zero input_loop_terminate: ; here RSI contains number of inputted values ; and memory from address array contains byte values (w/o the 99)
也就是说,对于用户输入32,72,13,0,16,99,地址0x1000处的存储器将具有5个字节的修改,其中包含(在六进制中): 20 48 0D 00 10 ?? ?? ?? ... 20 48 0D 00 10 ?? ?? ?? ... 20 48 0D 00 10 ?? ?? ?? ...
如果你是熟练的asm程序员,你不但可以通过寄存器索引,而且可以避免硬编码的array标签,所以你可能会做一个子程序作为参数目标地址(数组),最大数量:
; function to read user input,rsi = array address,rcx = max count ; does modify many other registers ; returns amount of inputted values in rax take_some_byte_values_from_user: jrcxz .error_zero_max_count ; validate count argument lea rdi,[rsi+rcx] ; rdi = address of first byte beyond buffer neg rcx ; rcx = -count (!) ; ^ small trick to make counter work also as index ; the index values will be: -200,-199,-198,... ; and that's perfect for that "address of byte beyond buffer" .input_loop: ; do input into AL = 0..99 integer (preserve RSI,RDI and RCX!) ... cmp al,99 je .input_loop_terminate mov [rdi+rcx],al ; store the new value into array inc rcx ; ++counter (and index) jnz .input_loop ; loop until counter is zero .input_loop_terminate: ; calculate inputted size into RAX lea rax,[rdi+rcx] ; address beyond last written value sub rax,rsi ; rax = count of inputted values ret .error_zero_max_count: xor eax,eax ; rax = 0,zero values were read ret
然后你可以像这样从主代码调用子程序:
... mov rsi,array ; rsi = address of reserved memory for data mov ecx,200 ; rcx = max values count call take_some_byte_values_from_user ; keep RAX (array.length = "0..200" value) somewhere test al,al ; as 200 was max,testing only 8 bits is OK jz no_input_from_user ; zero values were entered ...
对于word / dword / qword元素数组,x86在内存操作数中具有缩放因子,因此您可以使用索引值+1,地址值如下所示:
mov [array+4*rsi],eax ; store dword value into "array[rsi]"
对于其他大小的元素,通常使用指针而不是索引来更高效,并且通过add <pointer_reg>,<size_of_element>例如add rdi,96 )来移动到下一个元素,以避免每个访问的索引值相乘。
等等…读取值返回是以相同的方式工作,但是颠倒了操作数。
顺便说一句,这些例子没有像插入数组那么多,就像“覆盖”它。 计算机内存已经存在,并有一些值( .bss被libc或OS IIRC归零?否则会有一些垃圾可能在那里),所以它只是用用户的值覆盖旧的垃圾值。 仍然有200个字节的内存由resb保留,你的代码必须跟踪实际的大小(输入值的数量),知道用户输入结束的地方,以及垃圾数据开始的地方(或者你最终可以写入99值并将其作为“终止符”值,那么只需要数组的地址来扫描它的内容,并在找到99值时停止)。
编辑:
为了防止你还在为什么我有时使用方括号,有时候不用,这个Q + A看起来足够详细了,YASM语法与括号内的NASM相同: x86 Assembly中的立即数(方括号)和yasm
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。